package UI;

import Service.SecurityData;
import facecat.topin.core.*;

import java.text.*;
import java.util.*;

/**
 * 图表视图
 */
public class FCChart  extends FCView  {
    public FCChart()
    {
        m_indicatorColors.add(FCColor.rgb(100, 100, 100));
        m_indicatorColors.add(FCColor.rgb(206, 147, 27));
        m_indicatorColors.add(FCColor.rgb(150, 0, 150));
        m_indicatorColors.add(FCColor.rgb(255, 0, 0));
        m_indicatorColors.add(FCColor.rgb(0, 150, 150));
        m_indicatorColors.add(FCColor.rgb(0, 150, 0));
        m_indicatorColors.add(FCColor.rgb(59, 174, 218));
        m_indicatorColors.add(FCColor.rgb(50, 50, 50));
    }
    
    public boolean m_autoFillHScale = false; //是否填充满X轴
    public boolean m_allowDragChartDiv = false; //是否允许拖拽图层
    public double m_candleMax = 0; //蜡烛线的最大值
    public double m_candleMin = 0; //蜡烛线的最小值
    public double m_candleMaxRight = 0; //蜡烛线的右轴最大值
    public double m_candleMinRight = 0; //蜡烛线的右轴最小值
    public long m_crossTipColor = FCColor.rgb(50, 50, 50); //十字线标识的颜色
    public long m_crossLineColor = FCColor.rgb(100, 100, 100); //十字线的颜色
    public int m_candlePaddingTop = 30; //图表层的上边距
    public int m_candlePaddingBottom = 30; //图表层的下边距
    public int m_candleDigit = 2; //图表层保留小数的位数
    public double m_candleDivPercent = 0.5; //图表层的占比
    public int m_crossStopIndex = -1; //鼠标停留位置
    public String m_cycle = "day"; //周期
    public ArrayList<SecurityData> m_datas = new ArrayList<SecurityData>(); //子节点
    public long m_downColor = FCColor.rgb(15, 193, 118); //下跌颜色
    public int m_firstVisibleIndex = -1; //起始可见的索引
    public long m_gridColor = FCColor.rgb(150, 150, 150); //网格颜色
    public int m_lastVisibleIndex = -1; //结束可见的索引
    public int m_leftVScaleWidth = 80; //左轴宽度
    public boolean m_lastRecordIsVisible = true; //最后记录是否可见
    public double m_lastVisibleKey = 0; //最后可见的主键
    public double m_hScalePixel = 11; //蜡烛线的宽度
    public int m_hScaleHeight = 30; //X轴的高度
    public int m_hScaleTextDistance = 10; //X轴的文字间隔
    public String m_hScaleFormat = ""; //X轴的格式化字符，例如YYYY-mm-dd HH:MM:SS
    public double m_indMax = 0; //指标层的最大值
    public double m_indMin = 0; //指标的最小值
    public double m_indMax2 = 0; //指标层2的最大值
    public double m_indMin2 = 0; //指标层2的最小值
    public double m_indMaxRight = 0; //指标层的右轴最大值
    public double m_indMinRight = 0; //指标层的右轴最小值
    public double m_indMax2Right = 0; //指标层2的右轴最大值
    public double m_indMin2Right = 0; //指标层2的右轴最小值
    public int m_indDigit = 2; //指标层保留小数的位数
    public int m_indDigit2 = 2; //指标层2保留小数的位数
    public double m_indDivPercent = 0.3; //指标层的占比
    public double m_indDivPercent2 = 0.0; //指标层2的占比
    public int m_indPaddingTop = 20; //指标层的上边距
    public int m_indPaddingBottom = 20; //指标层的下边距
    public int m_indPaddingTop2 = 20; //指标层2的上边距
    public int m_indPaddingBottom2 = 20; //指标层2的下边距
    public ArrayList<Long> m_indicatorColors = new ArrayList<Long>(); //扩展图形
    public int m_lastValidIndex = -1; //最后有效数据索引
    public float m_lineWidthChart = 1;
    public String m_mainIndicator = ""; //主图指标
    public int m_magnitude = 1; //成交量的比例
    public long m_midColor = FCColor.None; //中间颜色
    public float m_offsetX = 0; //横向绘图偏移
    public ArrayList<FCPlot> m_plots = new ArrayList<FCPlot>(); //画线
    public int m_plotPointSizeChart = 20; //画线的选中点大小
    public int m_rightVScaleWidth = 0; //右轴宽度
    public int m_rightSpace = 0; //右侧空间
    public long m_scaleColor = FCColor.rgb(100, 100, 100); //刻度的颜色
    public String m_showIndicator = ""; //显示指标
    public String m_showIndicator2 = ""; //显示指标2
    public boolean m_showCrossLine = false; //是否显示十字线
    public int m_selectPlotPoint = -1; //选中画线的点
    public boolean m_startMovePlot = false; //选中画线
    public String m_selectShape = ""; //选中的图形
    public String m_selectShapeEx = ""; //选中的图形信息
    public ArrayList<BaseShape> m_shapes = new ArrayList<BaseShape>(); //扩展图形
    public FCPlot m_sPlot = null; //选中的线条
    public float m_targetOldX = 0; //缩小时旧的位置1
    public float m_targetOldX2 = 0; //放大时旧的位置2
    public FCPoint m_touchPosition = new FCPoint(0, 0); //鼠标坐标
    public long m_trendColor = FCColor.rgb(0, 0, 0); //分时线的颜色
    public double m_volMax = 0; //成交量层的最大值
    public double m_volMin = 0; //成交量层的最小值
    public double m_volMaxRight = 0; //成交量层的右轴最大值
    public double m_volMinRight = 0; //成交量层的右轴最小值
    public int m_volDigit = 0; //成交量层保留小数的位数
    public double m_volDivPercent = 0.2; //成交量层的占比
    public int m_volPaddingTop = 20; //成交量层的上边距
    public int m_volPaddingBottom = 0; //成交量层的下边距
    public int m_vScaleDistance = 35; //纵轴的间隔
    public String m_vScaleType = "standard"; //纵轴的类型 log10代表指数坐标
    public long m_upColor = FCColor.rgb(219, 68, 83); //上涨颜色
    public double m_kChart = 0;
    public double m_bChart = 0;
    public double m_oXChart = 0;
    public double m_oYChart = 0;
    public double m_rChart = 0;
    public double m_gridStep = 0; //网格计算临时变量
    public int m_gridDigit = 0; //网格计算临时变量
    //拖动滚动的缓存
    public int m_firstIndexCache = -1;
    public int m_firstTouchIndexCache = -1;
    public FCPoint m_firstTouchPointCache = new FCPoint(0, 0);
    public int m_lastIndexCache = -1;
    public int m_secondTouchIndexCache = -1;
    public FCPoint m_secondTouchPointCache = new FCPoint(0, 0);
    public int m_firstPaddingTop = 0;
    public int m_firtstPaddingBottom = 0;
    public FCPoint m_touchDownPoint = new FCPoint(0, 0);
    public String m_addingPlot = "";
    public double m_x4Chart = 0;
    public double m_y4Chart = 0;
    public double m_nHighChart = 0;
    public double m_nLowChart = 0;
    public double m_xChart = 0;
    public double m_yChart = 0;
    public double m_wChart = 0;
    public double m_hChart = 0;
    public double m_upSubValue = 0;
    public double m_downSubValue = 0;
    public String m_candleStyle = "rect";
    public String m_barStyle = "rect";
    public double m_firstOpen;
    public long m_hScaleTextColor = FCColor.None; //横轴的颜色
    public long m_vScaleTextColor = FCColor.None; //纵轴的颜色
    public ArrayList<Double> m_allema26 = new ArrayList<Double>();
    public ArrayList<Double> m_allema12 = new ArrayList<Double>();
    public ArrayList<Double> m_alldifarr = new ArrayList<Double>();
    public ArrayList<Double> m_alldeaarr = new ArrayList<Double>();
    public ArrayList<Double> m_allmacdarr = new ArrayList<Double>();
    public ArrayList<Double> m_bollUp = new ArrayList<Double>();
    public ArrayList<Double> m_bollDown = new ArrayList<Double>();
    public ArrayList<Double> m_bollMid = new ArrayList<Double>();
    public ArrayList<Double> m_bias1 = new ArrayList<Double>();
    public ArrayList<Double> m_bias2 = new ArrayList<Double>();
    public ArrayList<Double> m_bias3 = new ArrayList<Double>();
    public ArrayList<Double> m_kdjK = new ArrayList<Double>();
    public ArrayList<Double> m_kdjD = new ArrayList<Double>();
    public ArrayList<Double> m_kdjJ = new ArrayList<Double>();
    public ArrayList<Double> m_rsi1 = new ArrayList<Double>();
    public ArrayList<Double> m_rsi2 = new ArrayList<Double>();
    public ArrayList<Double> m_rsi3 = new ArrayList<Double>();
    public ArrayList<Double> m_roc = new ArrayList<Double>();
    public ArrayList<Double> m_rocMa = new ArrayList<Double>();
    public ArrayList<Double> m_wr1 = new ArrayList<Double>();
    public ArrayList<Double> m_wr2 = new ArrayList<Double>();
    public ArrayList<Double> m_cci = new ArrayList<Double>();
    public ArrayList<Double> m_bbi = new ArrayList<Double>();
    public ArrayList<Double> m_trix = new ArrayList<Double>();
    public ArrayList<Double> m_trixMa = new ArrayList<Double>();
    public ArrayList<Double> m_dma1 = new ArrayList<Double>();
    public ArrayList<Double> m_dma2 = new ArrayList<Double>();
    public ArrayList<Double> m_ma5 = new ArrayList<Double>();
    public ArrayList<Double> m_ma10 = new ArrayList<Double>();
    public ArrayList<Double> m_ma20 = new ArrayList<Double>();
    public ArrayList<Double> m_ma30 = new ArrayList<Double>();
    public ArrayList<Double> m_ma120 = new ArrayList<Double>();
    public ArrayList<Double> m_ma250 = new ArrayList<Double>();
    public ArrayList<Double> m_closeArr = new ArrayList<Double>();
    
    /**
     * 添加画线
     * @params firstTouch 是否第一次触摸
     * @params firstPoint 第一次触摸的坐标
     * @params secondTouch 是否第二次触摸
     * @params secondPoint 第二次触摸的坐标
     */
    public void addPlotDefault(boolean firstTouch, FCPoint firstPoint, boolean secondTouch, FCPoint secondPoint, String darkOrLight)
    {
        FCPoint mp = firstPoint;
        if (mp.y < getCandleDivHeight())
        {
            int touchIndex = getChartIndex(mp);
            if (touchIndex >= m_firstVisibleIndex &&
                touchIndex <= m_lastVisibleIndex)
            {
                if (m_addingPlot.equals("FiboTimezone"))
                {
                    int fIndex = touchIndex;
                    double fDate = getChartDateByIndex(fIndex);
                    double y = getChartValue(mp);
                    FCPlot newPlot = new FCPlot();
                    if (darkOrLight.equals("light") )
                    {
                        newPlot.m_lineColor = FCColor.rgb(0, 0, 0);
                        newPlot.m_pointColor = FCColor.rgba(0, 0, 0, 125);
                    }
                    else
                    {
                        newPlot.m_lineColor = FCColor.rgb(255, 255, 255);
                        newPlot.m_pointColor = FCColor.rgba(255, 255, 255, 125);
                    }
                    newPlot.m_key1 = fDate;
                    newPlot.m_value1 = y;
                    newPlot.m_plotType = m_addingPlot;
                    m_plots.add(newPlot);
                    m_sPlot = null;
                    FCPlot selectedPlot = selectPlot(mp);
                    if (selectedPlot != null)
                    {
                        m_sPlot = selectedPlot;
                    }
                }
                else if (m_addingPlot.equals("Triangle") ||
                    m_addingPlot.equals("CircumCycle") ||
                    m_addingPlot.equals("ParalleGram") ||
                    m_addingPlot.equals("AngleLine") ||
                    m_addingPlot.equals("Parallel") ||
                    m_addingPlot.equals("SymmetricTriangle"))
                {
                    int eIndex = touchIndex;
                    int bIndex = eIndex - 5;
                    if (bIndex >= 0)
                    {
                        double fDate = getChartDateByIndex(bIndex);
                        double sDate = getChartDateByIndex(eIndex);
                        double y = getChartValue(mp);
                        FCPlot newPlot = new FCPlot();
                        if (darkOrLight.equals("light") )
                        {
                            newPlot.m_lineColor = FCColor.rgb(0, 0, 0);
                            newPlot.m_pointColor = FCColor.rgba(0, 0, 0, 125);
                        }
                        else
                        {
                            newPlot.m_lineColor = FCColor.rgb(255, 255, 255);
                            newPlot.m_pointColor = FCColor.rgba(255, 255, 255, 125);
                        }
                        newPlot.m_key1 = fDate;
                        newPlot.m_value1 = y;
                        newPlot.m_key2 = sDate;
                        newPlot.m_value2 = y;
                        newPlot.m_key3 = sDate;
                        newPlot.m_value3 =
                            m_candleMin + (m_candleMax - m_candleMin) / 2;
                        newPlot.m_plotType = m_addingPlot;
                        m_plots.add(newPlot);
                        m_sPlot = null;
                        FCPlot selectedPlot = selectPlot(mp);
                        if (selectedPlot != null)
                        {
                            m_sPlot = selectedPlot;
                        }
                    }
                }
                else
                {
                    int eIndex = touchIndex;
                    int bIndex = eIndex - 5;
                    if (bIndex >= 0)
                    {
                        double fDate = getChartDateByIndex(bIndex);
                        double sDate = getChartDateByIndex(eIndex);
                        double y = getChartValue(mp);
                        FCPlot newPlot = new FCPlot();
                        if (darkOrLight.equals("light"))
                        {
                            newPlot.m_lineColor = FCColor.rgb(0, 0, 0);
                            newPlot.m_pointColor = FCColor.rgba(0, 0, 0, 125);
                        }
                        else
                        {
                            newPlot.m_lineColor = FCColor.rgb(255, 255, 255);
                            newPlot.m_pointColor = FCColor.rgba(255, 255, 255, 125);
                        }
                        newPlot.m_key1 = fDate;
                        newPlot.m_value1 = y;
                        newPlot.m_key2 = sDate;
                        newPlot.m_value2 = y;
                        newPlot.m_plotType = m_addingPlot;
                        m_plots.add(newPlot);
                        m_sPlot = null;
                        FCPlot selectedPlot = selectPlot(mp);
                        if (selectedPlot != null)
                        {
                            m_sPlot = selectedPlot;
                        }
                    }
                }
            }
        }
    }

    /**
     * 计算平均值
     * @params list 集合
     */
    public double avgValue(ArrayList<Double> list)
    {
        double sum = 0;
        int length = list.size();
        if (length > 0)
        {
            for (int i = 0; i < length; i++)
            {
                sum += list.get(i);
            }
            return sum / length;
        }
        return 0;
    }
    
    /**
     * 计算坐标轴
     * @params min 最小值
     * @params max 最大值
     * @params yLen 长度
     * @params maxSpan 最大间隔
     * @params minSpan 最小间隔
     * @params defCount 数量
     */
    public double chartGridScale(double min, double max, int yLen, double maxSpan, double minSpan, int defCount)
    {
        double sub = max - min;
        int nMinCount = (int)Math.ceil(yLen / maxSpan);
        int nMaxCount = (int)Math.floor(yLen / minSpan);
        int nCount = defCount;
        double logStep = sub / nCount;
        boolean start = false;
        double divisor = 0;
        int i = 0, nTemp = 0;
        m_gridStep = 0;
        m_gridDigit = 0;
        nCount = nMinCount > nCount ? nMinCount : nCount;
        nCount = nMaxCount > nCount ? nCount : nMaxCount;
        nCount = nCount > 1 ? nCount : 1;
        for (i = 15; i >= -6; i--)
        {
            divisor = Math.pow(10, i);
            if (divisor < 1)
            {
                m_gridDigit++;
            }
            nTemp = (int)Math.floor(logStep / divisor);
            if (start)
            {
                if (nTemp < 4)
                {
                    if (m_gridDigit > 0)
                    {
                        m_gridDigit--;
                    }
                }
                else if (nTemp >= 4 && nTemp <= 6)
                {
                    nTemp = 5;
                    m_gridStep += nTemp * divisor;
                }
                else
                {
                    m_gridStep += 10 * divisor;
                    if (m_gridDigit > 0)
                    {
                        m_gridDigit--;
                    }
                }
                break;
            }
            else if (nTemp > 0)
            {
                m_gridStep = nTemp * divisor + m_gridStep;
                logStep -= m_gridStep;
                start = true;
            }
        }
        return 0;
    }
   
    /**
     * 计算最大最小值
     */
    public void calculateChartMaxMin()
    {
        m_candleMax = 0;
        m_candleMin = 0;
        m_volMax = 0;
        m_volMin = 0;
        m_indMin = 0;
        m_indMin = 0;
        boolean load1 = false;
        boolean load2 = false;
        boolean load3 = false;
        boolean load4 = false;
        boolean isTrend = m_cycle.equals("trend");
        double firstOpen = m_firstOpen;
        if (m_datas.size() > 0)
        {
            int lastValidIndex = m_lastVisibleIndex;
            if (m_lastValidIndex != -1)
            {
                lastValidIndex = m_lastValidIndex;
            }
            for (int i = m_firstVisibleIndex; i <= lastValidIndex; i++)
            {
                if (i == m_firstVisibleIndex)
                {
                    if (isTrend)
                    {
                        m_candleMax = m_datas.get(i).m_close;
                        m_candleMin = m_datas.get(i).m_close;
                        if (firstOpen == 0)
                        {
                            firstOpen = m_datas.get(i).m_close;
                        }
                    }
                    else
                    {
                        m_candleMax = m_datas.get(i).m_high;
                        m_candleMin = m_datas.get(i).m_low;
                    }
                    m_volMax = m_datas.get(i).m_volume;
                    load1 = true;
                    load2 = true;
                    if (m_showIndicator.equals("MACD"))
                    {
                        m_indMax = m_alldifarr.get(i);
                        m_indMin = m_alldifarr.get(i);
                        load3 = true;
                    }
                    else if (m_showIndicator.equals("KDJ"))
                    {
                        m_indMax = m_kdjK.get(i);
                        m_indMin = m_kdjK.get(i);
                        load3 = true;
                    }
                    else if (m_showIndicator.equals("RSI"))
                    {
                        m_indMax = m_rsi1.get(i);
                        m_indMin = m_rsi1.get(i);
                        load3 = true;
                    }
                    else if (m_showIndicator.equals("BIAS"))
                    {
                        m_indMax = m_bias1.get(i);
                        m_indMin = m_bias1.get(i);
                        load3 = true;
                    }
                    else if (m_showIndicator.equals("ROC"))
                    {
                        m_indMax = m_roc.get(i);
                        m_indMin = m_roc.get(i);
                        load3 = true;
                    }
                    else if (m_showIndicator.equals("WR"))
                    {
                        m_indMax = m_wr1.get(i);
                        m_indMin = m_wr1.get(i);
                        load3 = true;
                    }
                    else if (m_showIndicator.equals("CCI"))
                    {
                        m_indMax = m_cci.get(i);
                        m_indMin = m_cci.get(i);
                        load3 = true;
                    }
                    else if (m_showIndicator.equals("BBI"))
                    {
                        m_indMax = m_bbi.get(i);
                        m_indMin = m_bbi.get(i);
                        load3 = true;
                    }
                    else if (m_showIndicator.equals("TRIX"))
                    {
                        m_indMax = m_trix.get(i);
                        m_indMin = m_trix.get(i);
                        load3 = true;
                    }
                    else if (m_showIndicator.equals("DMA"))
                    {
                        m_indMax = m_dma1.get(i);
                        m_indMin = m_dma1.get(i);
                        load3 = true;
                    }
                    if (m_showIndicator2.equals("MACD"))
                    {
                        m_indMax2 = m_alldifarr.get(i);
                        m_indMin2 = m_alldifarr.get(i);
                        load4 = true;
                    }
                    else if (m_showIndicator2.equals("KDJ"))
                    {
                        m_indMax2 = m_kdjK.get(i);
                        m_indMin2 = m_kdjK.get(i);
                        load4 = true;
                    }
                    else if (m_showIndicator2.equals("RSI"))
                    {
                        m_indMax2 = m_rsi1.get(i);
                        m_indMin2 = m_rsi1.get(i);
                        load4 = true;
                    }
                    else if (m_showIndicator2.equals("BIAS"))
                    {
                        m_indMax2 = m_bias1.get(i);
                        m_indMin2 = m_bias1.get(i);
                        load4 = true;
                    }
                    else if (m_showIndicator2.equals("ROC"))
                    {
                        m_indMax2 = m_roc.get(i);
                        m_indMin2 = m_roc.get(i);
                        load4 = true;
                    }
                    else if (m_showIndicator2.equals("WR"))
                    {
                        m_indMax2 = m_wr1.get(i);
                        m_indMin2 = m_wr1.get(i);
                        load4 = true;
                    }
                    else if (m_showIndicator2.equals("CCI"))
                    {
                        m_indMax2 = m_cci.get(i);
                        m_indMin2 = m_cci.get(i);
                        load4 = true;
                    }
                    else if (m_showIndicator2.equals("BBI"))
                    {
                        m_indMax2 = m_bbi.get(i);
                        m_indMin2 = m_bbi.get(i);
                        load4 = true;
                    }
                    else if (m_showIndicator2.equals("TRIX"))
                    {
                        m_indMax2 = m_trix.get(i);
                        m_indMin2 = m_trix.get(i);
                        load4 = true;
                    }
                    else if (m_showIndicator2.equals("DMA"))
                    {
                        m_indMax2 = m_dma1.get(i);
                        m_indMin2 = m_dma1.get(i);
                        load4 = true;
                    }
                }
                else
                {
                    if (isTrend)
                    {
                        if (m_candleMax < m_datas.get(i).m_close)
                        {
                            m_candleMax = m_datas.get(i).m_close;
                        }
                        if (m_candleMin > m_datas.get(i).m_close)
                        {
                            m_candleMin = m_datas.get(i).m_close;
                        }
                    }
                    else
                    {
                        if (m_candleMax < m_datas.get(i).m_high)
                        {
                            m_candleMax = m_datas.get(i).m_high;
                        }
                        if (m_candleMin > m_datas.get(i).m_low)
                        {
                            m_candleMin = m_datas.get(i).m_low;
                        }
                    }
                    if (m_volMax < m_datas.get(i).m_volume)
                    {
                        m_volMax = m_datas.get(i).m_volume;
                    }
                }
                if (m_showIndicator.equals("MACD"))
                {
                    if (m_indMax < m_alldifarr.get(i))
                    {
                        m_indMax = m_alldifarr.get(i);
                    }
                    if (m_indMax < m_alldeaarr.get(i))
                    {
                        m_indMax = m_alldeaarr.get(i);
                    }
                    if (m_indMax < m_allmacdarr.get(i))
                    {
                        m_indMax = m_allmacdarr.get(i);
                    }
                    if (m_indMin > m_alldifarr.get(i))
                    {
                        m_indMin = m_alldifarr.get(i);
                    }
                    if (m_indMin > m_alldeaarr.get(i))
                    {
                        m_indMin = m_alldeaarr.get(i);
                    }
                    if (m_indMin > m_allmacdarr.get(i))
                    {
                        m_indMin = m_allmacdarr.get(i);
                    }
                }
                else if (m_showIndicator.equals("KDJ"))
                {
                    if (m_indMax < m_kdjK.get(i))
                    {
                        m_indMax = m_kdjK.get(i);
                    }
                    if (m_indMax < m_kdjD.get(i))
                    {
                        m_indMax = m_kdjD.get(i);
                    }
                    if (m_indMax < m_kdjJ.get(i))
                    {
                        m_indMax = m_kdjJ.get(i);
                    }
                    if (m_indMin > m_kdjK.get(i))
                    {
                        m_indMin = m_kdjK.get(i);
                    }
                    if (m_indMin > m_kdjD.get(i))
                    {
                        m_indMin = m_kdjD.get(i);
                    }
                    if (m_indMin > m_kdjJ.get(i))
                    {
                        m_indMin = m_kdjJ.get(i);
                    }
                }
                else if (m_showIndicator.equals("RSI"))
                {
                    if (m_indMax < m_rsi1.get(i))
                    {
                        m_indMax = m_rsi1.get(i);
                    }
                    if (m_indMax < m_rsi2.get(i))
                    {
                        m_indMax = m_rsi2.get(i);
                    }
                    if (m_indMax < m_rsi3.get(i))
                    {
                        m_indMax = m_rsi3.get(i);
                    }
                    if (m_indMin > m_rsi1.get(i))
                    {
                        m_indMin = m_rsi1.get(i);
                    }
                    if (m_indMin > m_rsi2.get(i))
                    {
                        m_indMin = m_rsi2.get(i);
                    }
                    if (m_indMin > m_rsi3.get(i))
                    {
                        m_indMin = m_rsi3.get(i);
                    }
                }
                else if (m_showIndicator.equals("BIAS"))
                {
                    if (m_indMax < m_bias1.get(i))
                    {
                        m_indMax = m_bias1.get(i);
                    }
                    if (m_indMax < m_bias2.get(i))
                    {
                        m_indMax = m_bias2.get(i);
                    }
                    if (m_indMax < m_bias3.get(i))
                    {
                        m_indMax = m_bias3.get(i);
                    }
                    if (m_indMin > m_bias1.get(i))
                    {
                        m_indMin = m_bias1.get(i);
                    }
                    if (m_indMin > m_bias2.get(i))
                    {
                        m_indMin = m_bias2.get(i);
                    }
                    if (m_indMin > m_bias3.get(i))
                    {
                        m_indMin = m_bias3.get(i);
                    }
                }
                else if (m_showIndicator.equals("ROC"))
                {
                    if (m_indMax < m_roc.get(i))
                    {
                        m_indMax = m_roc.get(i);
                    }
                    if (m_indMax < m_rocMa.get(i))
                    {
                        m_indMax = m_rocMa.get(i);
                    }
                    if (m_indMin > m_roc.get(i))
                    {
                        m_indMin = m_roc.get(i);
                    }
                    if (m_indMin > m_rocMa.get(i))
                    {
                        m_indMin = m_rocMa.get(i);
                    }
                }
                else if (m_showIndicator.equals("WR"))
                {
                    if (m_indMax < m_wr1.get(i))
                    {
                        m_indMax = m_wr1.get(i);
                    }
                    if (m_indMax < m_wr2.get(i))
                    {
                        m_indMax = m_wr2.get(i);
                    }
                    if (m_indMin > m_wr1.get(i))
                    {
                        m_indMin = m_wr1.get(i);
                    }
                    if (m_indMin > m_wr2.get(i))
                    {
                        m_indMin = m_wr2.get(i);
                    }
                }
                else if (m_showIndicator.equals("CCI"))
                {
                    if (m_indMax < m_cci.get(i))
                    {
                        m_indMax = m_cci.get(i);
                    }
                    if (m_indMin > m_cci.get(i))
                    {
                        m_indMin = m_cci.get(i);
                    }
                }
                else if (m_showIndicator.equals("BBI"))
                {
                    if (m_indMax < m_bbi.get(i))
                    {
                        m_indMax = m_bbi.get(i);
                    }
                    if (m_indMin > m_bbi.get(i))
                    {
                        m_indMin = m_bbi.get(i);
                    }
                }
                else if (m_showIndicator.equals("TRIX"))
                {
                    if (m_indMax < m_trix.get(i))
                    {
                        m_indMax = m_trix.get(i);
                    }
                    if (m_indMax < m_trixMa.get(i))
                    {
                        m_indMax = m_trixMa.get(i);
                    }
                    if (m_indMin > m_trix.get(i))
                    {
                        m_indMin = m_trix.get(i);
                    }
                    if (m_indMin > m_trixMa.get(i))
                    {
                        m_indMin = m_trixMa.get(i);
                    }
                }
                else if (m_showIndicator.equals("DMA"))
                {
                    if (m_indMax < m_dma1.get(i))
                    {
                        m_indMax = m_dma1.get(i);
                    }
                    if (m_indMax < m_dma2.get(i))
                    {
                        m_indMax = m_dma2.get(i);
                    }
                    if (m_indMin > m_dma1.get(i))
                    {
                        m_indMin = m_dma1.get(i);
                    }
                    if (m_indMin > m_dma2.get(i))
                    {
                        m_indMin = m_dma2.get(i);
                    }
                }
                if (m_showIndicator2.equals("MACD"))
                {
                    if (m_indMax2 < m_alldifarr.get(i))
                    {
                        m_indMax2 = m_alldifarr.get(i);
                    }
                    if (m_indMax2 < m_alldeaarr.get(i))
                    {
                        m_indMax2 = m_alldeaarr.get(i);
                    }
                    if (m_indMax2 < m_allmacdarr.get(i))
                    {
                        m_indMax = m_allmacdarr.get(i);
                    }
                    if (m_indMin2 > m_alldifarr.get(i))
                    {
                        m_indMin2 = m_alldifarr.get(i);
                    }
                    if (m_indMin2 > m_alldeaarr.get(i))
                    {
                        m_indMin2 = m_alldeaarr.get(i);
                    }
                    if (m_indMin2 > m_allmacdarr.get(i))
                    {
                        m_indMin2 = m_allmacdarr.get(i);
                    }
                }
                else if (m_showIndicator2.equals("KDJ"))
                {
                    if (m_indMax2 < m_kdjK.get(i))
                    {
                        m_indMax2 = m_kdjK.get(i);
                    }
                    if (m_indMax2 < m_kdjD.get(i))
                    {
                        m_indMax2 = m_kdjD.get(i);
                    }
                    if (m_indMax2 < m_kdjJ.get(i))
                    {
                        m_indMax2 = m_kdjJ.get(i);
                    }
                    if (m_indMin2 > m_kdjK.get(i))
                    {
                        m_indMin2 = m_kdjK.get(i);
                    }
                    if (m_indMin2 > m_kdjD.get(i))
                    {
                        m_indMin2 = m_kdjD.get(i);
                    }
                    if (m_indMin2 > m_kdjJ.get(i))
                    {
                        m_indMin2 = m_kdjJ.get(i);
                    }
                }
                else if (m_showIndicator2.equals("RSI"))
                {
                    if (m_indMax2 < m_rsi1.get(i))
                    {
                        m_indMax2 = m_rsi1.get(i);
                    }
                    if (m_indMax2 < m_rsi2.get(i))
                    {
                        m_indMax2 = m_rsi2.get(i);
                    }
                    if (m_indMax2 < m_rsi3.get(i))
                    {
                        m_indMax2 = m_rsi3.get(i);
                    }
                    if (m_indMin2 > m_rsi1.get(i))
                    {
                        m_indMin2 = m_rsi1.get(i);
                    }
                    if (m_indMin2 > m_rsi2.get(i))
                    {
                        m_indMin2 = m_rsi2.get(i);
                    }
                    if (m_indMin2 > m_rsi3.get(i))
                    {
                        m_indMin2 = m_rsi3.get(i);
                    }
                }
                else if (m_showIndicator2.equals("BIAS"))
                {
                    if (m_indMax2 < m_bias1.get(i))
                    {
                        m_indMax2 = m_bias1.get(i);
                    }
                    if (m_indMax2 < m_bias2.get(i))
                    {
                        m_indMax2 = m_bias2.get(i);
                    }
                    if (m_indMax2 < m_bias3.get(i))
                    {
                        m_indMax2 = m_bias3.get(i);
                    }
                    if (m_indMin2 > m_bias1.get(i))
                    {
                        m_indMin2 = m_bias1.get(i);
                    }
                    if (m_indMin2 > m_bias2.get(i))
                    {
                        m_indMin2 = m_bias2.get(i);
                    }
                    if (m_indMin2 > m_bias3.get(i))
                    {
                        m_indMin2 = m_bias3.get(i);
                    }
                }
                else if (m_showIndicator2.equals("ROC"))
                {
                    if (m_indMax2 < m_roc.get(i))
                    {
                        m_indMax2 = m_roc.get(i);
                    }
                    if (m_indMax2 < m_rocMa.get(i))
                    {
                        m_indMax2 = m_rocMa.get(i);
                    }
                    if (m_indMin2 > m_roc.get(i))
                    {
                        m_indMin2 = m_roc.get(i);
                    }
                    if (m_indMin2 > m_rocMa.get(i))
                    {
                        m_indMin2 = m_rocMa.get(i);
                    }
                }
                else if (m_showIndicator2.equals("WR"))
                {
                    if (m_indMax2 < m_wr1.get(i))
                    {
                        m_indMax2 = m_wr1.get(i);
                    }
                    if (m_indMax2 < m_wr2.get(i))
                    {
                        m_indMax2 = m_wr2.get(i);
                    }
                    if (m_indMin2 > m_wr1.get(i))
                    {
                        m_indMin2 = m_wr1.get(i);
                    }
                    if (m_indMin2 > m_wr2.get(i))
                    {
                        m_indMin2 = m_wr2.get(i);
                    }
                }
                else if (m_showIndicator2.equals("CCI"))
                {
                    if (m_indMax2 < m_cci.get(i))
                    {
                        m_indMax2 = m_cci.get(i);
                    }
                    if (m_indMin2 > m_cci.get(i))
                    {
                        m_indMin2 = m_cci.get(i);
                    }
                }
                else if (m_showIndicator2.equals("BBI"))
                {
                    if (m_indMax2 < m_bbi.get(i))
                    {
                        m_indMax2 = m_bbi.get(i);
                    }
                    if (m_indMin2 > m_bbi.get(i))
                    {
                        m_indMin2 = m_bbi.get(i);
                    }
                }
                else if (m_showIndicator2.equals("TRIX"))
                {
                    if (m_indMax2 < m_trix.get(i))
                    {
                        m_indMax2 = m_trix.get(i);
                    }
                    if (m_indMax2 < m_trixMa.get(i))
                    {
                        m_indMax2 = m_trixMa.get(i);
                    }
                    if (m_indMin2 > m_trix.get(i))
                    {
                        m_indMin2 = m_trix.get(i);
                    }
                    if (m_indMin2 > m_trixMa.get(i))
                    {
                        m_indMin2 = m_trixMa.get(i);
                    }
                }
                else if (m_showIndicator2.equals("DMA"))
                {
                    if (m_indMax2 < m_dma1.get(i))
                    {
                        m_indMax2 = m_dma1.get(i);
                    }
                    if (m_indMax2 < m_dma2.get(i))
                    {
                        m_indMax2 = m_dma2.get(i);
                    }
                    if (m_indMin2> m_dma1.get(i))
                    {
                        m_indMin2 = m_dma1.get(i);
                    }
                    if (m_indMin2 > m_dma2.get(i))
                    {
                        m_indMin2 = m_dma2.get(i);
                    }
                }
            }
        }
        if (m_shapes.size() > 0)
        {
            int lastValidIndex = m_lastVisibleIndex;
            if (m_lastValidIndex != -1)
            {
                lastValidIndex = m_lastValidIndex;
            }
            for (int s = 0; s < m_shapes.size(); s++)
            {
                BaseShape shape = m_shapes.get(s);
                if (shape.m_datas.size() > 0)
                {
                    for (int i = m_firstVisibleIndex; i <= lastValidIndex; i++)
                    {
                        if (shape.m_divIndex == 0)
                        {
                            if (!load1 && i == m_firstVisibleIndex)
                            {
                                if (shape.m_leftOrRight)
                                {
                                    m_candleMax = shape.m_datas.get(i);
                                    m_candleMin = shape.m_datas.get(i);
                                }
                                else
                                {
                                    m_candleMaxRight = shape.m_datas.get(i);
                                    m_candleMinRight = shape.m_datas.get(i);
                                }
                                load1 = true;
                            }
                            else
                            {
                                if (shape.m_leftOrRight)
                                {
                                    if (shape.m_datas.get(i) > m_candleMax)
                                    {
                                        m_candleMax = shape.m_datas.get(i);
                                    }
                                    if (shape.m_datas.get(i) < m_candleMin)
                                    {
                                        m_candleMin = shape.m_datas.get(i);
                                    }
                                }
                                else
                                {
                                    if (shape.m_datas.get(i) > m_candleMaxRight)
                                    {
                                        m_candleMaxRight = shape.m_datas.get(i);
                                    }
                                    if (shape.m_datas.get(i) < m_candleMinRight)
                                    {
                                        m_candleMinRight = shape.m_datas.get(i);
                                    }
                                }
                            }
                        }
                        else if (shape.m_divIndex == 1)
                        {
                            if (!load2 && i == m_firstVisibleIndex)
                            {
                                if (shape.m_leftOrRight)
                                {
                                    m_volMax = shape.m_datas.get(i);
                                    m_volMin = shape.m_datas.get(i);
                                }
                                else
                                {
                                    m_volMaxRight = shape.m_datas.get(i);
                                    m_volMinRight = shape.m_datas.get(i);
                                }
                                load2 = true;
                            }
                            else
                            {
                                if (shape.m_leftOrRight)
                                {
                                    if (shape.m_datas.get(i) > m_volMax)
                                    {
                                        m_volMax = shape.m_datas.get(i);
                                    }
                                    if (shape.m_datas.get(i) < m_volMin)
                                    {
                                        m_volMin = shape.m_datas.get(i);
                                    }
                                }
                                else
                                {
                                    if (shape.m_datas.get(i) > m_volMaxRight)
                                    {
                                        m_volMaxRight = shape.m_datas.get(i);
                                    }
                                    if (shape.m_datas.get(i) < m_volMinRight)
                                    {
                                        m_volMinRight = shape.m_datas.get(i);
                                    }
                                }
                            }
                        }
                        else if (shape.m_divIndex == 2)
                        {
                            if (!load3 && i == m_firstVisibleIndex)
                            {
                                if (shape.m_leftOrRight)
                                {
                                    m_indMax = shape.m_datas.get(i);
                                    m_indMin = shape.m_datas.get(i);
                                }
                                else
                                {
                                    m_indMaxRight = shape.m_datas.get(i);
                                    m_indMinRight = shape.m_datas.get(i);
                                }
                                load3 = true;
                            }
                            else
                            {
                                if (shape.m_leftOrRight)
                                {
                                    if (shape.m_datas.get(i) > m_indMax)
                                    {
                                        m_indMax = shape.m_datas.get(i);
                                    }
                                    if (shape.m_datas.get(i) < m_indMin)
                                    {
                                        m_indMin = shape.m_datas.get(i);
                                    }
                                }
                                else
                                {
                                    if (shape.m_datas.get(i) > m_indMaxRight)
                                    {
                                        m_indMaxRight = shape.m_datas.get(i);
                                    }
                                    if (shape.m_datas.get(i) < m_indMinRight)
                                    {
                                        m_indMinRight = shape.m_datas.get(i);
                                    }
                                }
                            }
                        }
                        else if (shape.m_divIndex == 3)
                        {
                            if (!load4 && i == m_firstVisibleIndex)
                            {
                                if (shape.m_leftOrRight)
                                {
                                    m_indMax2 = shape.m_datas.get(i);
                                    m_indMin2 = shape.m_datas.get(i);
                                }
                                else
                                {
                                    m_indMax2Right = shape.m_datas.get(i);
                                    m_indMin2Right = shape.m_datas.get(i);
                                }
                                load4 = true;
                            }
                            else
                            {
                                if (shape.m_leftOrRight)
                                {
                                    if (shape.m_datas.get(i) > m_indMax2)
                                    {
                                        m_indMax2 = shape.m_datas.get(i);
                                    }
                                    if (shape.m_datas.get(i) < m_indMin2)
                                    {
                                        m_indMin2 = shape.m_datas.get(i);
                                    }
                                }
                                else
                                {
                                    if (shape.m_datas.get(i) > m_indMax2Right)
                                    {
                                        m_indMax2Right = shape.m_datas.get(i);
                                    }
                                    if (shape.m_datas.get(i) < m_indMin2Right)
                                    {
                                        m_indMin2Right = shape.m_datas.get(i);
                                    }
                                }
                            }
                        }
                    }
                }
                if (shape.m_datas2.size() > 0)
                {
                    for (int i = m_firstVisibleIndex; i <= lastValidIndex; i++)
                    {
                        if (shape.m_divIndex == 0)
                        {
                            if (shape.m_leftOrRight)
                            {
                                if (shape.m_datas2.get(i) > m_candleMax)
                                {
                                    m_candleMax = shape.m_datas2.get(i);
                                }
                                if (shape.m_datas2.get(i) < m_candleMin)
                                {
                                    m_candleMin = shape.m_datas2.get(i);
                                }
                            }
                            else
                            {
                                if (shape.m_datas2.get(i) > m_candleMaxRight)
                                {
                                    m_candleMaxRight = shape.m_datas2.get(i);
                                }
                                if (shape.m_datas2.get(i) < m_candleMinRight)
                                {
                                    m_candleMinRight = shape.m_datas2.get(i);
                                }
                            }
                        }
                        else if (shape.m_divIndex == 1)
                        {
                            if (shape.m_leftOrRight)
                            {
                                if (shape.m_datas2.get(i) > m_volMax)
                                {
                                    m_volMax = shape.m_datas2.get(i);
                                }
                                if (shape.m_datas2.get(i) < m_volMin)
                                {
                                    m_volMin = shape.m_datas2.get(i);
                                }
                            }
                            else
                            {
                                if (shape.m_datas2.get(i) > m_volMaxRight)
                                {
                                    m_volMaxRight = shape.m_datas2.get(i);
                                }
                                if (shape.m_datas2.get(i) < m_volMinRight)
                                {
                                    m_volMinRight = shape.m_datas2.get(i);
                                }
                            }
                        }
                        else if (shape.m_divIndex == 2)
                        {
                            if (shape.m_leftOrRight)
                            {
                                if (shape.m_datas2.get(i) > m_indMax)
                                {
                                    m_indMax = shape.m_datas2.get(i);
                                }
                                if (shape.m_datas2.get(i) < m_indMin)
                                {
                                    m_indMin = shape.m_datas2.get(i);
                                }
                            }
                            else
                            {
                                if (shape.m_datas2.get(i) > m_indMaxRight)
                                {
                                    m_indMaxRight = shape.m_datas2.get(i);
                                }
                                if (shape.m_datas2.get(i) < m_indMinRight)
                                {
                                    m_indMinRight = shape.m_datas2.get(i);
                                }
                            }
                        }
                        else if (shape.m_divIndex == 3)
                        {
                            if (shape.m_leftOrRight)
                            {
                                if (shape.m_datas2.get(i) > m_indMax2)
                                {
                                    m_indMax2 = shape.m_datas2.get(i);
                                }
                                if (shape.m_datas2.get(i) < m_indMin2)
                                {
                                    m_indMin2 = shape.m_datas2.get(i);
                                }
                            }
                            else
                            {
                                if (shape.m_datas2.get(i) > m_indMax2Right)
                                {
                                    m_indMax2Right = shape.m_datas2.get(i);
                                }
                                if (shape.m_datas2.get(i) < m_indMin2Right)
                                {
                                    m_indMin2Right = shape.m_datas2.get(i);
                                }
                            }
                        }
                    }
                }
            }
        }
        if (isTrend)
        {
            double subMax = Math.max(Math.abs(m_candleMax - firstOpen),
                Math.abs(m_candleMin - firstOpen));
            m_candleMax = firstOpen + subMax;
            m_candleMin = firstOpen - subMax;
        }
        else
        {
            if (m_candleMax == 0 && m_candleMin == 0)
            {
                m_candleMax = 1;
                m_candleMin = -1;
            }
            if (m_volMax == 0 && m_volMin == 0)
            {
                m_volMax = 1;
                m_volMin = -1;
            }
            if (m_indMax == 0 && m_indMin == 0)
            {
                m_indMax = 1;
                m_indMin = -1;
            }
            if (m_indMax2 == 0 && m_indMin2 == 0)
            {
                m_indMax2 = 1;
                m_indMin2 = -1;
            }
            if (m_candleMaxRight == 0 && m_candleMinRight == 0)
            {
                m_candleMaxRight = 1;
                m_candleMinRight = -1;
            }
            if (m_volMaxRight == 0 && m_volMinRight == 0)
            {
                m_volMaxRight = 1;
                m_volMinRight = -1;
            }
            if (m_indMaxRight == 0 && m_indMinRight == 0)
            {
                m_indMaxRight = 1;
                m_indMinRight = -1;
            }
            if (m_indMax2Right == 0 && m_indMin2Right == 0)
            {
                m_indMax2Right = 1;
                m_indMin2Right = -1;
            }
        }
    } 
    
    /**
     * 检查最后可见索引
     */
    public void checkChartLastVisibleIndex()
    {
        int dataCount = m_datas.size();
        int workingAreaWidth = getChartWorkAreaWidth();
        int maxVisibleRecord = getChartMaxVisibleCount(m_hScalePixel, workingAreaWidth);
        if (m_firstVisibleIndex < 0)
        {
            m_firstVisibleIndex = 0;
        }
        if (m_lastVisibleIndex >= m_firstVisibleIndex + maxVisibleRecord - 1 || m_lastVisibleIndex < dataCount - 1)
        {
            m_lastVisibleIndex = m_firstVisibleIndex + maxVisibleRecord - 1;
        }
        if (m_lastVisibleIndex > dataCount - 1)
        {
            m_lastVisibleIndex = dataCount - 1;
        }
        if (m_datas.size() > 0 && m_lastVisibleIndex != -1)
        {
            m_lastVisibleKey = m_datas.get(m_lastVisibleIndex).m_date;
            if (m_lastVisibleIndex == m_datas.size() - 1)
            {
                m_lastRecordIsVisible = true;
            }
            else
            {
                m_lastRecordIsVisible = false;
            }
        }
        else
        {
            m_lastVisibleKey = 0;
            m_lastRecordIsVisible = true;
        }
    }
    
    /**
     * 清除缓存数据方法
     */
    public void clearDataArr()
    {
        m_allema12 = new ArrayList<Double>();
        m_allema26 = new ArrayList<Double>();
        m_alldifarr = new ArrayList<Double>();
        m_alldeaarr = new ArrayList<Double>();
        m_allmacdarr = new ArrayList<Double>();
        m_bollUp = new ArrayList<Double>();
        m_bollDown = new ArrayList<Double>();
        m_bollMid = new ArrayList<Double>();
        m_bias1 = new ArrayList<Double>();
        m_bias2 = new ArrayList<Double>();
        m_bias3 = new ArrayList<Double>();
        m_kdjK = new ArrayList<Double>();
        m_kdjD = new ArrayList<Double>();
        m_kdjJ = new ArrayList<Double>();
        m_rsi1 = new ArrayList<Double>();
        m_rsi2 = new ArrayList<Double>();
        m_rsi3 = new ArrayList<Double>();
        m_roc = new ArrayList<Double>();
        m_rocMa = new ArrayList<Double>();
        m_wr1 = new ArrayList<Double>();
        m_wr2 = new ArrayList<Double>();
        m_cci = new ArrayList<Double>();
        m_bbi = new ArrayList<Double>();
        m_trix = new ArrayList<Double>();
        m_trixMa = new ArrayList<Double>();
        m_dma1 = new ArrayList<Double>();
        m_dma2 = new ArrayList<Double>();
        m_ma5 = new ArrayList<Double>();
        m_ma10 = new ArrayList<Double>();
        m_ma20 = new ArrayList<Double>();
        m_ma30 = new ArrayList<Double>();
        m_ma120 = new ArrayList<Double>();
        m_ma250 = new ArrayList<Double>();
    }
    /**
     * 获取数据
     */
    public void calcChartIndicator()
    {
        clearDataArr();
        ArrayList<Double> closeArr = new ArrayList<Double>();
        ArrayList<Double> highArr = new ArrayList<Double>();
        ArrayList<Double> lowArr = new ArrayList<Double>();
        if (m_datas.size() > 0)
        {
            for (int i = 0; i < m_datas.size(); i++)
            {
                closeArr.add(m_datas.get(i).m_close);
                highArr.add(m_datas.get(i).m_high);
                lowArr.add(m_datas.get(i).m_low);
            }
        }
        m_closeArr = closeArr;
        if (m_mainIndicator.equals("BOLL"))
        {
            getBollData(closeArr, 20, m_bollUp, m_bollMid, m_bollDown);
        }
        else if (m_mainIndicator.equals("MA"))
        {
            m_ma5 = maValue(closeArr, 5);
            m_ma10 = maValue(closeArr, 10);
            m_ma20 = maValue(closeArr, 20);
            m_ma30 = maValue(closeArr, 30);
            m_ma120 = maValue(closeArr, 120);
            m_ma250 = maValue(closeArr, 250);
        }
        if (m_showIndicator.equals("BIAS") || m_showIndicator2.equals("BIAS"))
        {
            getBIASData(closeArr, 6, 12, 24, m_bias1, m_bias2, m_bias3);
        }
        if (m_showIndicator.equals("DMA") || m_showIndicator2.equals("DMA"))
        {
            getDMAData(closeArr, 10, 50, m_dma1, m_dma2);
        }
        if (m_showIndicator.equals("BBI") || m_showIndicator2.equals("BBI"))
        {
            getBBIData(closeArr, 3, 6, 12, 24, m_bbi);
        }
        if (m_showIndicator.equals("RSI") || m_showIndicator2.equals("RSI"))
        {
            getRSIData(closeArr, 6, 12, 24, m_rsi1, m_rsi2, m_rsi3);
        }
        if (m_showIndicator.equals("ROC") || m_showIndicator2.equals("ROC"))
        {
            getRocData(closeArr, 12, 6, m_roc, m_rocMa);
        }
        if (m_showIndicator.equals("TRIX") || m_showIndicator2.equals("TRIX"))
        {
            getTRIXData(closeArr, 9, m_trix, m_trixMa);
        }
        if (m_showIndicator.equals("KDJ") || m_showIndicator2.equals("KDJ"))
        {
            getKDJData(
                highArr, lowArr, closeArr, 9, 3, 3, m_kdjK, m_kdjD, m_kdjJ);
        }
        if (m_showIndicator.equals("WR") || m_showIndicator2.equals("WR"))
        {
            getWRData(highArr, lowArr, closeArr, 5, 10, m_wr1, m_wr2);
        }
        if (m_showIndicator.equals("CCI") || m_showIndicator2.equals("CCI"))
        {
            getCCIData(highArr, lowArr, closeArr, 14, m_cci);
        }
        if (m_showIndicator.equals("MACD") || m_showIndicator2.equals("MACD"))
        {
            //缓存MACD数据
            m_allema12.add(closeArr.get(0));
            m_allema26.add(closeArr.get(0));
            m_alldeaarr.add(0.0);
            for (int i = 1; i < closeArr.size(); i++)
            {
                m_allema12.add(getEMA(12, closeArr.get(i), m_allema12.get(i-1)));
                m_allema26.add(getEMA(26, closeArr.get(i), m_allema26.get(i-1)));
            }
            m_alldifarr = getDIF(m_allema12, m_allema26);
            for (int i = 1; i < m_alldifarr.size(); i++)
            {
                m_alldeaarr
                    .add(m_alldeaarr.get(i - 1) * 8 / 10 + m_alldifarr.get(i) * 2 / 10);
            }
            m_allmacdarr = getMACD(m_alldifarr, m_alldeaarr);
        }
        calculateChartMaxMin();
    }
    
    /**
     * 绘制线条
     * @params paint 绘图对象
     * @params clipRect 裁剪区域
     * @params divIndex 图层
     * @params datas 数据
     * @params color 颜色
     * @params selected 是否选中
     */
    public void drawChartLines(FCPaint paint, FCRect clipRect, int divIndex, ArrayList<Double> datas, Long color, boolean selected)
    {
        ArrayList<FCPoint> drawPoints = new ArrayList<FCPoint>();
            int maxVisibleRecord = getChartMaxVisibleCount(m_hScalePixel, getChartWorkAreaWidth());
            int lastValidIndex = m_lastVisibleIndex;
            if (m_lastValidIndex != -1)
            {
                lastValidIndex = m_lastValidIndex;
            }
            for (int i = m_firstVisibleIndex; i <= lastValidIndex; i++)
            {
                int x = getChartX(i);
                double value = datas.get(i);
                int y = getChartY(divIndex, value);
                drawPoints.add(new FCPoint((int)x, (int)y));
                if (selected)
                {
                    int kPInterval = maxVisibleRecord / 30;
                    if (kPInterval < 2)
                    {
                        kPInterval = 3;
                    }
                    if (i % kPInterval == 0)
                    {
                        paint.fillRect(color, (int)(x - 3), (int)(y - 3), (int)(x + 3), (int)(y + 3));
                    }
                }
            }
            FCPoint[] apt = new FCPoint[drawPoints.size()];
            for(int i = 0; i < drawPoints.size(); i++){
                apt[i] = drawPoints.get(i);
            }
            paint.drawPolyline(color, (float)m_lineWidthChart, 0, apt);
    }
    
    /**
     * 绘制线条到右轴
     * @params paint 绘图对象
     * @params clipRect 裁剪区域
     * @params divIndex 图层
     * @params datas 数据
     * @params color 颜色
     * @params selected 是否选中
     */
    public void drawChartLinesInRight(FCPaint paint, FCRect clipRect, int divIndex, ArrayList<Double> datas, long color, boolean selected)
    {
     ArrayList<FCPoint> drawPoints = new ArrayList<FCPoint>();
            int maxVisibleRecord = getChartMaxVisibleCount(m_hScalePixel, getChartWorkAreaWidth());
            int lastValidIndex = m_lastVisibleIndex;
            if (m_lastValidIndex != -1)
            {
                lastValidIndex = m_lastValidIndex;
            }
            for (int i = m_firstVisibleIndex; i <= lastValidIndex; i++)
            {
                int x = getChartX(i);
                double value = datas.get(i);
                int y = getChartYInRight(divIndex, value);
                drawPoints.add(new FCPoint((int)x, (int)y));
                if (selected)
                {
                    int kPInterval = maxVisibleRecord / 30;
                    if (kPInterval < 2)
                    {
                        kPInterval = 3;
                    }
                    if (i % kPInterval == 0)
                    {
                        paint.fillRect(color, (int)(x - 3), (int)(y - 3), (int)(x + 3), (int)(y + 3));
                    }
                }
            }
            FCPoint[] apt = new FCPoint[drawPoints.size()];
            for(int i = 0; i < drawPoints.size(); i++){
                apt[i] = drawPoints.get(i);
            }
            paint.drawPolyline(color, (float)m_lineWidthChart, 0, apt);
      
    }

    /**
     * 绘制画线工具
     * @params paint 绘图对象
     * @params clipRect 裁剪区
     */
    public void drawChartPlot(FCPaint paint, FCRect clipRect)
    {
        FCSize size = getSize();
        int divHeight = getCandleDivHeight();

        paint.setClip(new FCRect(Math.max(clipRect.left, m_leftVScaleWidth), Math.max(clipRect.top, 0), Math.min(clipRect.right, size.cx - m_rightVScaleWidth), Math.min(clipRect.bottom, divHeight)));
        for (int i = 0; i < m_plots.size(); i++)
        {
            FCPlot plot = m_plots.get(i);
            int index1 = 0, index2 = 0, index3 = 0;
            int mpx1 = 0, mpy1 = 0, mpx2 = 0, mpy2 = 0, mpx3 = 0, mpy3 = 0;
            if (plot.m_plotType.equals("LRLine") ||
                plot.m_plotType.equals("LRChannel") ||
                plot.m_plotType.equals("LRBand"))
            {
                ArrayList<Double> list = new ArrayList<Double>();
                index1 = getChartIndexByDate(plot.m_key1);
                index2 = getChartIndexByDate(plot.m_key2);
                int minIndex = Math.min(index1, index2);
                int maxIndex = Math.max(index1, index2);
                for (int j = minIndex; j <= maxIndex; j++)
                {
                    list.add(m_datas.get(j).m_close);
                }
                linearRegressionEquation(list);
                plot.m_value1 = m_bChart;
                plot.m_value2 = m_kChart * (maxIndex - minIndex + 1) + m_bChart;
            }
            else if (plot.m_plotType.equals("BoxLine" )||
                plot.m_plotType.equals("TironeLevels" )||
                plot.m_plotType.equals("QuadrantLines"))
            {
                getCandleRange(plot);
                double nHigh = m_nHighChart, nLow = m_nLowChart;
                index1 = getChartIndexByDate(plot.m_key1);
                index2 = getChartIndexByDate(plot.m_key2);
                plot.m_key1 = getChartDateByIndex(Math.min(index1, index2));
                plot.m_key2 = getChartDateByIndex(Math.max(index1, index2));
                plot.m_value1 = nHigh;
                plot.m_value2 = nLow;
            }
            if (plot.m_key1 > 0)
            {
                index1 = getChartIndexByDate(plot.m_key1);
                mpx1 = getChartX(index1);
                mpy1 = getChartY(0, plot.m_value1);
                if (m_sPlot == plot)
                {
                    paint.fillEllipse(plot.m_pointColor, (int)(mpx1 - m_plotPointSizeChart), (int)(mpy1 - m_plotPointSizeChart), (int)(mpx1 + m_plotPointSizeChart), (int)(mpy1 + m_plotPointSizeChart));
                }
            }
            if (plot.m_key2 > 0)
            {
                index2 = getChartIndexByDate(plot.m_key2);
                mpx2 = getChartX(index2);
                mpy2 = getChartY(0, plot.m_value2);
                if (m_sPlot == plot)
                {
                    paint.fillEllipse(
                        plot.m_pointColor,
                        (int)(mpx2 - m_plotPointSizeChart),
                        (int)(mpy2 - m_plotPointSizeChart),
                        (int)(mpx2 + m_plotPointSizeChart),
                        (int)(mpy2 + m_plotPointSizeChart));
                }
            }
            if (plot.m_key3 > 0)
            {
                index3 = getChartIndexByDate(plot.m_key3);
                mpx3 = getChartX(index3);
                mpy3 = getChartY(0, plot.m_value3);
                if (m_sPlot == plot)
                {
                    paint.fillEllipse(
                        plot.m_pointColor,
                        (int)(mpx3 - m_plotPointSizeChart),
                        (int)(mpy3 - m_plotPointSizeChart),
                        (int)(mpx3 + m_plotPointSizeChart),
                        (int)(mpy3 + m_plotPointSizeChart));
                }
            }
            if (plot.m_plotType.equals("Line"))
            {
                lineXY(mpx1, mpy1, mpx2, mpy2, 0, 0);
                if (mpx2 == mpx1)
                {
                    paint.drawLine(
                        plot.m_lineColor, plot.m_lineWidth, 0, mpx1, 0, mpx1, divHeight);
                }
                else
                {
                    double newX1 = m_leftVScaleWidth;
                    double newY1 = newX1 * m_kChart + m_bChart;
                    double newX2 = size.cx - m_rightVScaleWidth;
                    double newY2 = newX2 * m_kChart + m_bChart;
                    paint.drawLine(
                        plot.m_lineColor, plot.m_lineWidth, 0, (int)newX1, (int)newY1, (int)newX2, (int)newY2);
                }
            }
            else if (plot.m_plotType.equals("ArrowSegment"))
            {
                int arrowSize = 24;
                double slopy = 0, cosy = 0, siny = 0;
                slopy = Math.atan2(mpy1 - mpy2, mpx1 - mpx2);
                cosy = Math.cos(slopy);
                siny = Math.sin(slopy);
                FCPoint ptPoint = new FCPoint(0, 0);
                ptPoint.x = mpx2;
                ptPoint.y = mpy2;
                ArrayList<FCPoint> pts = new ArrayList<FCPoint>();
                pts.add(new FCPoint(0, 0));
                pts.add(new FCPoint(0, 0));
                pts.add(new FCPoint(0, 0));
                pts.set(0,ptPoint);
                pts.set(1,  new FCPoint((int)(ptPoint.x + (arrowSize * cosy - (arrowSize / 2.0 * siny) + 0.5)), (int)(ptPoint.y + (arrowSize * siny + (arrowSize / 2.0 * cosy) + 0.5))));
                pts.set(2, new FCPoint((int)(ptPoint.x + (arrowSize * cosy + arrowSize / 2.0 * siny + 0.5)), (int)(ptPoint.y - (arrowSize / 2.0 * cosy - arrowSize * siny + 0.5))));
                arrowSize = 20;
                FCPoint ptPoint2 = new FCPoint(0, 0);
                ptPoint2.x = mpx2;
                ptPoint2.y = mpy2;
                ArrayList<FCPoint> pts2 = new ArrayList<FCPoint>();
                pts2.add(new FCPoint(0, 0));
                pts2.add(new FCPoint(0, 0));
                pts2.add(new FCPoint(0, 0));
                pts2.set(0,ptPoint2);
                pts2.set(1, new FCPoint((int)(ptPoint2.x + (arrowSize * cosy - (arrowSize / 2.0 * siny) + 0.5)), (int)(ptPoint2.y + (arrowSize * siny + (arrowSize / 2.0 * cosy) + 0.5))));
                pts2.set(2,new FCPoint((int)(ptPoint2.x + (arrowSize * cosy + arrowSize / 2.0 * siny + 0.5)), (int)(ptPoint2.y - (arrowSize / 2.0 * cosy - arrowSize * siny + 0.5))));
                lineXY(pts2.get(1).x, pts2.get(1).y, pts2.get(2).x, pts2.get(2).y, 0, 0);
                double newX1 = 0, newY1 = 0, newX2 = 0, newY2 = 0;
                if (pts2.get(1).x > pts2.get(2).x)
                {
                    newX1 = pts2.get(2).x + (pts2.get(1).x - pts2.get(2).x) / 3;
                    newX2 = pts2.get(2).x + (pts2.get(1).x - pts2.get(2).x) * 2 / 3;
                }
                else
                {
                    newX1 = pts2.get(1).x + (pts2.get(2).x - pts2.get(1).x) / 3;
                    newX2 = pts2.get(1).x + (pts2.get(2).x - pts2.get(1).x) * 2 / 3;
                }
                if (m_kChart == 0 && m_bChart == 0)
                {
                    if (pts2.get(1).y > pts2.get(2).y)
                    {
                        newY1 = pts2.get(2).y + (pts2.get(1).y - pts2.get(2).y) / 3;
                        newY2 = pts2.get(2).y + (pts2.get(1).y - pts2.get(2).y) * 2 / 3;
                    }
                    else
                    {
                        newY1 = pts2.get(1).y + (pts2.get(2).y - pts2.get(1).y) / 3;
                        newY2 = pts2.get(1).y + (pts2.get(2).y - pts2.get(1).y) * 2 / 3;
                    }
                }
                else
                {
                    newY1 = (m_kChart * newX1) + m_bChart;
                    newY2 = (m_kChart * newX2) + m_bChart;
                }
                pts2.set(1, new FCPoint((int)newX1, (int)newY1));
                pts2.set(2, new FCPoint((int)newX2, (int)newY2));
                ArrayList<FCPoint> drawPoints = new ArrayList<FCPoint>();
                drawPoints.add(new FCPoint(0, 0));
                drawPoints.add(new FCPoint(0, 0));
                drawPoints.add(new FCPoint(0, 0));
                drawPoints.add(new FCPoint(0, 0));
                drawPoints.add(new FCPoint(0, 0));
                drawPoints.add(new FCPoint(0, 0));
                drawPoints.set(0, new FCPoint(ptPoint.x, ptPoint.y));
                drawPoints.set(1, new FCPoint(pts.get(1).x, pts.get(1).y));
                if (mpy1 >= mpy2)
                {
                    drawPoints.set(2, new FCPoint(pts2.get(1).x, pts2.get(1).y));
                }
                else
                {
                    drawPoints.set(2, new FCPoint(pts2.get(2).x, pts2.get(2).y));
                }
                drawPoints.set(3, new FCPoint(mpx1, mpy1));
                if (mpy1 >= mpy2)
                {
                    drawPoints.set(4, new FCPoint(pts2.get(2).x, pts2.get(2).y));
                }
                else
                {
                    drawPoints.set(4, new FCPoint(pts2.get(1).x, pts2.get(1).y));
                }
                drawPoints.set(5, new FCPoint(pts.get(2).x, pts.get(2).y));
                FCPoint[] apt = new FCPoint[drawPoints.size()];
                for(int j = 0; j < drawPoints.size(); j++){
                apt[i] = drawPoints.get(i);
            }
                paint.fillPolygon(plot.m_lineColor, apt);
            }
            else if (plot.m_plotType.equals("AngleLine"))
            {
                lineXY(mpx1, mpy1, mpx2, mpy2, 0, 0);
                if (mpx2 == mpx1)
                {
                    paint.drawLine(
                        plot.m_lineColor, plot.m_lineWidth, 0, mpx1, 0, mpx1, divHeight);
                }
                else
                {
                    double newX1 = m_leftVScaleWidth;
                    double newY1 = newX1 * m_kChart + m_bChart;
                    double newX2 = size.cx - m_rightVScaleWidth;
                    double newY2 = newX2 * m_kChart + m_bChart;
                    paint.drawLine(
                        plot.m_lineColor, plot.m_lineWidth, 0, (int)newX1, (int)newY1, (int)newX2, (int)newY2);
                }
                lineXY(mpx1, mpy1, mpx3, mpy3, 0, 0);
                if (mpx3 == mpx1)
                {
                    paint.drawLine(
                        plot.m_lineColor, plot.m_lineWidth, 0, mpx1, 0, mpx1, divHeight);
                }
                else
                {
                    double newX1 = m_leftVScaleWidth;
                    double newY1 = newX1 * m_kChart + m_bChart;
                    double newX2 = size.cx - m_rightVScaleWidth;
                    double newY2 = newX2 * m_kChart + m_bChart;
                    paint.drawLine(
                        plot.m_lineColor, plot.m_lineWidth, 0, (int)newX1, (int)newY1, (int)newX2, (int)newY2);
                }
            }
            else if (plot.m_plotType.equals("Parallel"))
            {
                lineXY(mpx1, mpy1, mpx2, mpy2, 0, 0);
                if (mpx2 == mpx1)
                {
                    paint.drawLine(
                        plot.m_lineColor, plot.m_lineWidth, 0, mpx1, 0, mpx1, divHeight);
                }
                else
                {
                    double newX1 = m_leftVScaleWidth;
                    double newY1 = newX1 * m_kChart + m_bChart;
                    double newX2 = size.cx - m_rightVScaleWidth;
                    double newY2 = newX2 * m_kChart + m_bChart;
                    paint.drawLine(
                        plot.m_lineColor, plot.m_lineWidth, 0, (int)newX1, (int)newY1, (int)newX2, (int)newY2);
                }
                double newB = mpy3 - m_kChart * mpx3;
                if (mpx2 == mpx1)
                {
                    paint.drawLine(
                        plot.m_lineColor, plot.m_lineWidth, 0, mpx3, 0, mpx3, divHeight);
                }
                else
                {
                    double newX1 = m_leftVScaleWidth;
                    double newY1 = newX1 * m_kChart + newB;
                    double newX2 = size.cx - m_rightVScaleWidth;
                    double newY2 = newX2 * m_kChart + newB;
                    paint.drawLine(
                        plot.m_lineColor, plot.m_lineWidth, 0, (int)newX1, (int)newY1, (int)newX2, (int)newY2);
                }
            }
            else if (plot.m_plotType.equals("Percent"))
            {
                ArrayList<Integer> list = getPercentParams((double)mpy1, (double)mpy2);
                ArrayList<String> texts = new ArrayList<String>();
                texts.add("0%");
                texts.add("25%");
                texts.add("50%");
                texts.add("75%");
                texts.add("100%");
                for (int j = 0; j < list.size(); j++)
                {
                    paint.drawLine(plot.m_lineColor, plot.m_lineWidth, 0, m_leftVScaleWidth,
                        list.get(j), size.cx - m_rightVScaleWidth, list.get(j));
                    FCSize tSize = paint.textSize(texts.get(j), getFont());
                    paint.drawText(texts.get(j), getTextColor(), getFont(),
                        new FCRect(m_leftVScaleWidth + 5, list.get(j) - tSize.cy - 2, m_leftVScaleWidth + 5 + tSize.cx, list.get(j) - 2));
                }
            }
            else if (plot.m_plotType.equals("FiboTimezone"))
            {
                int fValue = 1;
                int aIndex = index1;
                int pos = 1;
                paint.drawLine(
                    plot.m_lineColor, plot.m_lineWidth, 0, mpx1, 0, mpx1, divHeight);
                FCSize tSize = paint.textSize("1", getFont());
                paint.drawText(
                    "1", getTextColor(), getFont(), new FCRect(mpx1, divHeight - tSize.cy, mpx1 + tSize.cx, divHeight));
                while (aIndex + fValue <= m_lastVisibleIndex)
                {
                    fValue = fibonacciValue(pos);
                    int newIndex = aIndex + fValue;
                    double newX = getChartX(newIndex);
                    paint.drawLine(
                        plot.m_lineColor, plot.m_lineWidth, 0, (int)newX, 0, (int)newX, divHeight);
                    FCSize tSize2 = paint.textSize(FCTran.doubleToStr(fValue), getFont());
                    paint.drawText(FCTran.doubleToStr(fValue), getTextColor(), getFont(), new FCRect((int)newX,
                        divHeight - tSize2.cy, (int)newX + tSize2.cx, divHeight));
                    pos++;
                }
            }
            else if (plot.m_plotType.equals("SpeedResist"))
            {
                paint.drawLine(plot.m_lineColor, plot.m_lineWidth, 0, mpx1, mpy1, mpx2, mpy2);
                if (mpx1 != mpx2 && mpy1 != mpy2)
                {
                    FCPoint firstP = new FCPoint(mpx2, mpy2 - (mpy2 - mpy1) / 3);
                    FCPoint secondP = new FCPoint(mpx2, mpy2 - (mpy2 - mpy1) * 2 / 3);
                    FCPoint startP = new FCPoint(mpx1, mpy1);
                    double fK = 0, fB = 0, sK = 0, sB = 0;
                    lineXY(startP.x, startP.y, firstP.x, firstP.y, 0, 0);
                    fK = m_kChart;
                    fB = m_bChart;
                    lineXY(startP.x, startP.y, secondP.x, secondP.y, 0, 0);
                    sK = m_kChart;
                    sB = m_bChart;
                    double newYF = 0, newYS = 0;
                    double newX = 0;
                    if (mpx2 > mpx1)
                    {
                        newYF = fK * (size.cx - m_rightVScaleWidth) + fB;
                        newYS = sK * (size.cx - m_rightVScaleWidth) + sB;
                        newX = (size.cx - m_rightVScaleWidth);
                    }
                    else
                    {
                        newYF = fB;
                        newYS = sB;
                        newX = m_leftVScaleWidth;
                    }
                    paint.drawLine(
                        plot.m_lineColor, plot.m_lineWidth, 0, startP.x, startP.y, (int)newX, (int)newYF);
                    paint.drawLine(
                        plot.m_lineColor, plot.m_lineWidth, 0, startP.x, startP.y, (int)newX, (int)newYS);
                }
            }
            else if (plot.m_plotType.equals("FiboFanline"))
            {
                paint.drawLine(plot.m_lineColor, plot.m_lineWidth, 0, mpx1, mpy1, mpx2, mpy2);
                if (mpx1 != mpx2 && mpy1 != mpy2)
                {
                    FCPoint firstP = new FCPoint((int)mpx2, (int)(mpy2 - (mpy2 - mpy1) * 0.382));
                    FCPoint secondP = new FCPoint((int)mpx2, (int)(mpy2 - (mpy2 - mpy1) * 0.5));
                    FCPoint thirdP = new FCPoint((int)mpx2, (int)(mpy2 - (mpy2 - mpy1) * 0.618));
                    FCPoint startP = new FCPoint((int)mpx1, (int)mpy1);
                    ArrayList<FCPoint> listP = new ArrayList<FCPoint>();
                    listP.add(firstP);
                    listP.add(secondP);
                    listP.add(thirdP);
                    int listSize = listP.size();
                    for (int j = 0; j < listSize; j++)
                    {
                        //获取直线参数
                        lineXY(startP.x, startP.y, listP.get(j).x, listP.get(j).y, 0, 0);
                        double newX = 0;
                        double newY = 0;
                        if (mpx2 > mpx1)
                        {
                            newY = m_kChart * (size.cx - m_rightVScaleWidth) +
                                m_bChart;
                            newX = (size.cx - m_rightVScaleWidth);
                        }
                        else
                        {
                            newY = m_bChart;
                            newX = m_leftVScaleWidth;
                        }
                        paint.drawLine(plot.m_lineColor, plot.m_lineWidth, 0, startP.x, startP.y,
                            (int)newX, (int)newY);
                    }
                }
            }
            else if (plot.m_plotType.equals("LRLine"))
            {
                paint.drawLine(plot.m_lineColor, plot.m_lineWidth, 0, mpx1, mpy1, mpx2, mpy2);
            }
            else if (plot.m_plotType.equals("LRBand"))
            {
                paint.drawLine(plot.m_lineColor, plot.m_lineWidth, 0, mpx1, mpy1, mpx2, mpy2);
                getLRBandRange(plot, m_kChart, m_bChart);
                mpy1 = getChartY(0, plot.m_value1 + m_upSubValue);
                mpy2 = getChartY(0, plot.m_value2 + m_upSubValue);
                paint.drawLine(plot.m_lineColor, plot.m_lineWidth, 0, mpx1, mpy1, mpx2, mpy2);
                mpy1 = getChartY(0, plot.m_value1 - m_downSubValue);
                mpy2 = getChartY(0, plot.m_value2 - m_downSubValue);
                paint.drawLine(plot.m_lineColor, plot.m_lineWidth, 0, mpx1, mpy1, mpx2, mpy2);
            }
            else if (plot.m_plotType.equals("LRChannel"))
            {
                getLRBandRange(plot, m_kChart, m_bChart);
                lineXY(mpx1, mpy1, mpx2, mpy2, 0, 0);
                double rightX = size.cx - m_rightVScaleWidth;
                double rightY = rightX * m_kChart + m_bChart;
                paint.drawLine(
                    plot.m_lineColor, plot.m_lineWidth, 0, mpx1, mpy1, (int)rightX, (int)rightY);
                mpy1 = getChartY(0, plot.m_value1 + m_upSubValue);
                mpy2 = getChartY(0, plot.m_value2 + m_upSubValue);
                lineXY(mpx1, mpy1, mpx2, mpy2, 0, 0);
                rightY = rightX * m_kChart + m_bChart;
                paint.drawLine(
                    plot.m_lineColor, plot.m_lineWidth, 0, mpx1, mpy1, (int)rightX, (int)rightY);
                mpy1 = getChartY(0, plot.m_value1 - m_downSubValue);
                mpy2 = getChartY(0, plot.m_value2 - m_downSubValue);
                lineXY(mpx1, mpy1, mpx2, mpy2, 0, 0);
                rightY = rightX * m_kChart + m_bChart;
                paint.drawLine(
                    plot.m_lineColor, plot.m_lineWidth, 0, mpx1, mpy1, (int)rightX, (int)rightY);
            }
            else if (plot.m_plotType.equals("Segment"))
            {
                paint.drawLine(plot.m_lineColor, plot.m_lineWidth, 0, mpx1, mpy1, mpx2, mpy2);
            }
            else if (plot.m_plotType.equals("Ray"))
            {
                lineXY(mpx1, mpy1, mpx2, mpy2, 0, 0);
                if (m_kChart != 0 || m_bChart != 0)
                {
                    double leftX = m_leftVScaleWidth;
                    double leftY = leftX * m_kChart + m_bChart;
                    double rightX = size.cx - m_rightVScaleWidth;
                    double rightY = rightX * m_kChart + m_bChart;
                    if (mpx1 >= mpx2)
                    {
                        paint.drawLine(
                            plot.m_lineColor, plot.m_lineWidth, 0, (int)leftX, (int)leftY, mpx1, mpy1);
                    }
                    else
                    {
                        paint.drawLine(
                            plot.m_lineColor, plot.m_lineWidth, 0, mpx1, mpy1, (int)rightX, (int)rightY);
                    }
                }
                //垂直时
                else
                {
                    if (mpy1 >= mpy2)
                    {
                        paint.drawLine(
                            plot.m_lineColor, plot.m_lineWidth, 0, mpx1, mpy1, mpx1, 0);
                    }
                    else
                    {
                        paint.drawLine(
                            plot.m_lineColor, plot.m_lineWidth, 0, mpx1, mpy1, mpx1, divHeight);
                    }
                }
            }
            else if (plot.m_plotType.equals("Triangle"))
            {
                paint.drawLine(plot.m_lineColor, plot.m_lineWidth, 0, mpx1, mpy1, mpx2, mpy2);
                paint.drawLine(plot.m_lineColor, plot.m_lineWidth, 0, mpx2, mpy2, mpx3, mpy3);
                paint.drawLine(plot.m_lineColor, plot.m_lineWidth, 0, mpx1, mpy1, mpx3, mpy3);
            }
            else if (plot.m_plotType.equals("SymmetricTriangle"))
            {
                if (mpx2 != mpx1)
                {
                    double a = (double)(mpy2 - mpy1) / (double)(mpx2 - mpx1);
                    double b = mpy1 - a * mpx1;
                    double c = -a;
                    double d = mpy3 - c * mpx3;
                    double leftX = m_leftVScaleWidth;
                    double leftY = leftX * a + b;
                    double rightX = size.cx - m_rightVScaleWidth;
                    double rightY = rightX * a + b;
                    paint.drawLine(
                        plot.m_lineColor, plot.m_lineWidth, 0, (int)leftX, (int)leftY, (int)rightX, (int)rightY);
                    leftY = leftX * c + d;
                    rightY = rightX * c + d;
                    paint.drawLine(
                        plot.m_lineColor, plot.m_lineWidth, 0, (int)leftX, (int)leftY, (int)rightX, (int)rightY);
                }
                else
                {
                    paint.drawLine(
                        plot.m_lineColor, plot.m_lineWidth, 0, mpx1, 0, mpx1, divHeight);
                    paint.drawLine(
                        plot.m_lineColor, plot.m_lineWidth, 0, mpx3, 0, mpx3, divHeight);
                }
            }
            else if (plot.m_plotType.equals("Rect"))
            {
                int sX1 = Math.min(mpx1, mpx2);
                int sY1 = Math.min(mpy1, mpy2);
                int sX2 = Math.max(mpx1, mpx2);
                int sY2 = Math.max(mpy1, mpy2);
                paint.drawRect(plot.m_lineColor, plot.m_lineWidth, 0, sX1, sY1, sX2, sY2);
            }
            else if (plot.m_plotType.equals("Cycle"))
            {
                int r = (int)Math.sqrt(
                    (Math.abs((mpx2 - mpx1) * (mpx2 - mpx1) + (mpy2 - mpy1) * (mpy2 - mpy1))));
                paint.drawEllipse(plot.m_lineColor, plot.m_lineWidth, 0, mpx1 - r, mpy1 - r,
                    mpx1 + r, mpy1 + r);
            }
            else if (plot.m_plotType.equals("CircumCycle"))
            {
                ellipseOR(mpx1, mpy1, mpx2, mpy2, mpx3, mpy3);
                paint.drawEllipse(
                    plot.m_lineColor,
                    plot.m_lineWidth,
                    0,
                    (int)(m_oXChart - m_rChart),
                    (int)(m_oYChart - m_rChart),
                    (int)(m_oXChart + m_rChart),
                    (int)(m_oYChart + m_rChart));
            }
            else if (plot.m_plotType.equals("Ellipse"))
            {
                double x1 = 0, y1 = 0, x2 = 0, y2 = 0;
                if (mpx1 <= mpx2)
                {
                    x1 = mpx2;
                    y1 = mpy2;
                    x2 = mpx1;
                    y2 = mpy1;
                }
                else
                {
                    x1 = mpx1;
                    y1 = mpy1;
                    x2 = mpx2;
                    y2 = mpy2;
                }
                double x = x1 - (x1 - x2);
                double y = 0;
                double width = (x1 - x2) * 2;
                double height = 0;
                if (y1 >= y2)
                {
                    height = (y1 - y2) * 2;
                }
                else
                {
                    height = (y2 - y1) * 2;
                }
                y = y2 - height / 2;
                paint.drawEllipse(
                    plot.m_lineColor, plot.m_lineWidth, 0, (int)x, (int)y, (int)(x + width), (int)(y + height));
            }
            else if (plot.m_plotType.equals("ParalleGram"))
            {
                parallelogram(mpx1, mpy1, mpx2, mpy2, mpx3, mpy3);
                paint.drawLine(plot.m_lineColor, plot.m_lineWidth, 0, mpx1, mpy1, mpx2, mpy2);
                paint.drawLine(plot.m_lineColor, plot.m_lineWidth, 0, mpx2, mpy2, mpx3, mpy3);
                paint.drawLine(plot.m_lineColor, plot.m_lineWidth, 0, mpx3, mpy3,
                    (int)m_x4Chart, (int)m_y4Chart);
                paint.drawLine(plot.m_lineColor, plot.m_lineWidth, 0, (int)m_x4Chart,
                    (int)m_y4Chart, mpx1, mpy1);
            }
            else if (plot.m_plotType.equals("BoxLine"))
            {
                int sX1 = Math.min(mpx1, mpx2);
                int sY1 = Math.min(mpy1, mpy2);
                int sX2 = Math.max(mpx1, mpx2);
                int sY2 = Math.max(mpy1, mpy2);
                paint.drawRect(plot.m_lineColor, plot.m_lineWidth, 0, sX1, sY1, sX2, sY2);
                String bText = FCTran.intToStr(Math.abs(index2 - index1) + 1);
                FCSize tSize = paint.textSize(bText, getFont());
                paint.drawText(FCTran.intToStr(Math.abs(index2 - index1) + 1), getTextColor(),
                    getFont(), new FCRect(sX1 + 2, sY1 + 2, sX1 + 2 + tSize.cx, sY1 + 2 + tSize.cy));
                ArrayList<Double> closeList = new ArrayList<Double>();
                for (int j = index1; j <= index2; j++)
                {
                    closeList.add(m_datas.get(j).m_close);
                }
                double avgClose = avgValue(closeList);
                int closeY = getChartY(0, avgClose);
                paint.drawLine(
                    plot.m_lineColor, plot.m_lineWidth, 0, sX1, closeY, sX2, closeY);
                String drawAvg = FCTran.getValueByDigit(avgClose, m_candleDigit);
                tSize = paint.textSize(drawAvg, getFont());
                paint.drawText(
                    drawAvg, getTextColor(), getFont(), new FCRect(sX1 + 2, closeY - tSize.cy - 2, sX1 + 2 + tSize.cx, closeY - 2));
            }
            else if (plot.m_plotType.equals("TironeLevels"))
            {
                int sX1 = Math.min(mpx1, mpx2);
                int sY1 = Math.min(mpy1, mpy2);
                int sX2 = Math.max(mpx1, mpx2);
                int sY2 = Math.max(mpy1, mpy2);
                paint.drawLine(plot.m_lineColor, plot.m_lineWidth, 0, sX1, sY1, sX2, sY1);
                paint.drawLine(plot.m_lineColor, plot.m_lineWidth, 0, sX1, sY2, sX2, sY2);
                paint.drawLine(plot.m_lineColor, plot.m_lineWidth, 0, sX1 + (sX2 - sX1) / 2,
                    sY1, sX1 + (sX2 - sX1) / 2, sY2);
                double t2 = m_nHighChart - (m_nHighChart - m_nLowChart) / 3,
                    t3 = m_nHighChart - (m_nHighChart - m_nLowChart) / 2,
                    t4 = m_nHighChart - 2 * (m_nHighChart - m_nLowChart) / 3;
                ArrayList<Double> tList = new ArrayList<Double>();
                tList.add(t2);
                tList.add(t3);
                tList.add(t4);
                for (int j = 0; j < tList.size(); j++)
                {
                    int y = getChartY(0, tList.get(j));
                    //画直线
                    paint.drawLine(plot.m_lineColor, plot.m_lineWidth, 0, m_leftVScaleWidth,
                        y, size.cx - m_rightVScaleWidth, y);
                    String str = FCTran.getValueByDigit(tList.get(j), m_candleDigit);
                    FCSize tSize = paint.textSize(str, getFont());
                    paint.drawText(str, getTextColor(), getFont(),
                        new FCRect(m_leftVScaleWidth + 2, y - tSize.cy - 2, m_leftVScaleWidth + 2 + tSize.cx, y - 2));
                }
            }
            else if (plot.m_plotType.equals("QuadrantLines"))
            {
                int sX1 = Math.min(mpx1, mpx2);
                int sY1 = Math.min(mpy1, mpy2);
                int sX2 = Math.max(mpx1, mpx2);
                int sY2 = Math.max(mpy1, mpy2);
                paint.drawLine(plot.m_lineColor, plot.m_lineWidth, 0, sX1, sY1, sX2, sY1);
                paint.drawLine(plot.m_lineColor, plot.m_lineWidth, 0, sX1, sY2, sX2, sY2);
                double t2 = m_nHighChart - (m_nHighChart - m_nLowChart) / 4,
                    t3 = m_nHighChart - (m_nHighChart - m_nLowChart) / 2,
                    t4 = m_nHighChart - 3 * (m_nHighChart - m_nLowChart) / 4;
                ArrayList<Double> tList = new ArrayList<Double>();
                tList.add(t2);
                tList.add(t3);
                tList.add(t4);
                for (int j = 0; j < tList.size(); j++)
                {
                    int y = getChartY(0, tList.get(j));
                    //画直线
                    paint.drawLine(plot.m_lineColor, plot.m_lineWidth, 0, sX1, y, sX2, y);
                }
            }
            else if (plot.m_plotType.equals("GoldenRatio"))
            {
                double sY1 = Math.min(mpy1, mpy2);
                double sY2 = Math.max(mpy1, mpy2);
                ArrayList<Double> ranges = new ArrayList<Double>();
                ranges.add(0.0);
                ranges.add(0.236);
                ranges.add(0.382);
                ranges.add(0.5);
                ranges.add(0.618);
                ranges.add(0.809);
                ranges.add(1.0);
                ranges.add(1.382);
                ranges.add(1.618);
                ranges.add(2.0);
                ranges.add(2.382);
                ranges.add(2.618);
                for (int j = 0; j < ranges.size(); j++)
                {
                    double newY = sY1 <= sY2
                        ? sY1 + (sY2 - sY1) * ranges.get(j)
                        : sY2 + (sY1 - sY2) * (1 - ranges.get(j));
                    paint.drawLine(plot.m_lineColor, plot.m_lineWidth, 0, m_leftVScaleWidth,
                        (int)newY, size.cx - m_rightVScaleWidth, (int)newY);
                    FCPoint newPoint = new FCPoint(0, (int)newY);
                    double value = getCandleDivValue(newPoint);
                    String str = FCTran.getValueByDigit(value, m_candleDigit);
                    FCSize tSize = paint.textSize(str, getFont());
                    paint.drawText(str, getTextColor(), getFont(),
                        new FCRect(m_leftVScaleWidth + 2, (int)newY - tSize.cy - 2, m_leftVScaleWidth + 2 + tSize.cx, (int)newY - 2));
                }
            }
        }
        paint.setClip(clipRect);
    }

     /**
     * 绘制图表
     * @params paint 绘图对象
     * @params clipRect 裁剪区
     */
    public void drawChartStock(FCPaint paint, FCRect clipRect)
    {
        int candleHeight = getCandleDivHeight();
        int volHeight = getVolDivHeight();
        int indHeight = getIndDivHeight();
        int indHeight2 = getIndDivHeight2();
        FCSize size = getSize();
        boolean isTrend = m_cycle.equals("trend");
        int cWidth = (int)((m_hScalePixel - 3) / 2);
        if (cWidth < 0)
        {
            cWidth = 0;
        }
        int lastValidIndex = m_lastVisibleIndex;
        if (m_lastValidIndex != -1)
        {
            lastValidIndex = m_lastValidIndex;
        }
        if (m_datas.size() > 0)
        {
            int maxVisibleRecord = getChartMaxVisibleCount(m_hScalePixel, getChartWorkAreaWidth());
            paint.setClip(new FCRect(Math.max(clipRect.left, m_leftVScaleWidth), Math.max(clipRect.top, 0), Math.min(clipRect.right, size.cx - m_rightVScaleWidth), Math.min(clipRect.bottom, candleHeight)));
            if (isTrend)
            {
                FCPoint[] points = new FCPoint[lastValidIndex - m_firstVisibleIndex + 1];
                for (int i = m_firstVisibleIndex; i <= lastValidIndex; i++)
                {
                    int x = getChartX(i);
                    double close = m_datas.get(i).m_close;
                    int closeY = getChartY(0, close);
                    points[i - m_firstVisibleIndex] = new FCPoint(x, closeY);
                }
                paint.drawPolyline(m_trendColor, m_lineWidthChart, 0, points);
            }else {
                boolean hasMinTag = false, hasMaxTag = false;
                for (int i = m_firstVisibleIndex; i <= lastValidIndex; i++) {
                    int x = getChartX(i);
                    double open = m_datas.get(i).m_open;
                    double close = m_datas.get(i).m_close;
                    double high = m_datas.get(i).m_high;
                    double low = m_datas.get(i).m_low;
                    int openY = getChartY(0, open);
                    int closeY = getChartY(0, close);
                    int highY = getChartY(0, high);
                    int lowY = getChartY(0, low);
                    if (close >= open) {
                        if (close == open && m_midColor != FCColor.None) {
                            paint.drawLine(
                                    m_midColor, m_lineWidthChart, 0, x, highY, x, lowY);
                        } else {
                            paint.drawLine(
                                    m_upColor, m_lineWidthChart, 0, x, highY, x, lowY);
                        }
                        if (cWidth > 0) {
                            if (close == open) {
                                if (m_midColor != FCColor.None) {
                                    paint.drawLine(m_midColor, m_lineWidthChart, 0, x - cWidth,
                                            closeY, x + cWidth, closeY);
                                } else {
                                    paint.drawLine(m_upColor, m_lineWidthChart, 0, x - cWidth,
                                            closeY, x + cWidth, closeY);
                                }
                            } else {
                                if (m_candleStyle.equals("rect2")) {
                                    paint.fillRect(
                                            m_backColor, x - cWidth, closeY, x + cWidth, openY);
                                    paint.drawRect(m_upColor, 1, 0, x - cWidth, closeY, x + cWidth + 1, openY);
                                } else {
                                    paint.fillRect(
                                            m_upColor, x - cWidth, closeY, x + cWidth, openY);
                                }
                            }
                        }
                    } else {
                        paint.drawLine(
                                m_downColor, m_lineWidthChart, 0, x, highY, x, lowY);
                        if (cWidth > 0) {
                            paint.fillRect(
                                    m_downColor, x - cWidth, openY, x + cWidth, closeY);
                        }
                    }
                    if (m_selectShape.equals("CANDLE")) {
                        int kPInterval = maxVisibleRecord / 30;
                        if (kPInterval < 2) {
                            kPInterval = 3;
                        }
                        if (i % kPInterval == 0) {
                            paint.fillRect(
                                    m_indicatorColors.get(0), x - 3, closeY - 3, x + 3, closeY + 3);
                        }
                    }
                    if (!hasMaxTag) {
                        if (high == m_candleMax) {
                            String tag = FCTran.getValueByDigit(high, m_candleDigit);
                            FCSize tSize = paint.textSize(tag, getFont());
                            paint.drawText(tag, getTextColor(), getFont(), new FCRect(x - tSize.cx / 2,
                                    highY - tSize.cy / 2 - 2, x + tSize.cx / 2, highY + tSize.cy / 2 - 2));
                            hasMaxTag = true;
                        }
                    }
                    if (!hasMinTag) {
                        if (low == m_candleMin) {
                            String tag = FCTran.getValueByDigit(low, m_candleDigit);
                            FCSize tSize = paint.textSize(tag, getFont());
                            paint.drawText(tag, getTextColor(), getFont(), new FCRect(x - tSize.cx / 2,
                                    lowY + 2 + tSize.cy / 2, x + tSize.cx / 2,
                                    lowY + 2 + tSize.cy * 3 / 2));
                            hasMinTag = true;
                        }
                    }
                }
            }
            paint.setClip(clipRect);
            if(volHeight > 0) {
                for (int i = m_firstVisibleIndex; i <= lastValidIndex; i++) {
                    int x = getChartX(i);
                    double open = m_datas.get(i).m_open;
                    double close = m_datas.get(i).m_close;
                    double volume = m_datas.get(i).m_volume;
                    int volY = getChartY(1, volume);
                    int zeroY = getChartY(1, 0);
                    if (close >= open) {
                        if (isTrend) {
                            paint.drawLine(m_upColor, m_lineWidthChart, 0, x,
                                    volY, x, zeroY);
                        } else {
                            if (cWidth > 0) {
                                if (m_barStyle.equals("rect2")) {
                                    paint.fillRect(
                                            m_backColor, x - cWidth, volY, x + cWidth, zeroY);
                                    paint.drawRect(m_upColor, 1, 0, x - cWidth, volY, x + cWidth + 1, zeroY);
                                } else {
                                    paint.fillRect(
                                            m_upColor, x - cWidth, volY, x + cWidth, zeroY);
                                }
                            } else {
                                paint.drawLine(m_upColor, m_lineWidthChart, 0, x - cWidth,
                                        volY, x + cWidth, zeroY);
                            }
                        }
                    } else {
                        if (isTrend) {
                            paint.drawLine(m_downColor, m_lineWidthChart, 0, x,
                                    volY, x, zeroY);
                        } else {
                            if (cWidth > 0) {
                                paint.fillRect(
                                        m_downColor, x - cWidth, volY, x + cWidth, zeroY);
                            } else {
                                paint.drawLine(m_downColor, m_lineWidthChart, 0,
                                        x - cWidth, volY, x + cWidth, zeroY);
                            }
                        }
                    }
                    if (m_selectShape.equals("VOL")) {
                        int kPInterval = maxVisibleRecord / 30;
                        if (kPInterval < 2) {
                            kPInterval = 3;
                        }
                        if (i % kPInterval == 0) {
                            paint.fillRect(
                                    m_indicatorColors.get(0), x - 3, volY - 3, x + 3, volY + 3);
                        }
                    }
                }
            }
            if (!isTrend)
            {
                paint.setClip(new FCRect(Math.max(clipRect.left, m_leftVScaleWidth), Math.max(clipRect.top, 0), Math.min(clipRect.right, size.cx - m_rightVScaleWidth), Math.min(clipRect.bottom, candleHeight)));
                if (m_mainIndicator.equals("BOLL"))
                {
                    drawChartLines(paint, clipRect, 0,
                        m_bollMid, m_indicatorColors.get(0),
                        (m_selectShape.equals(m_mainIndicator) &&
                                m_selectShapeEx.equals("MID")) ? true : false);
                    drawChartLines(paint, clipRect, 0,
                        m_bollUp, m_indicatorColors.get(1),
                        (m_selectShape.equals(m_mainIndicator) &&
                                m_selectShapeEx.equals("UP")) ? true : false);
                    drawChartLines(paint, clipRect, 0,
                        m_bollDown, m_indicatorColors.get(2),
                        (m_selectShape.equals(m_mainIndicator) &&
                                m_selectShapeEx.equals("DOWN")) ? true : false);
                }
                else if (m_mainIndicator.equals("MA"))
                {
                    drawChartLines(paint, clipRect, 0,
                        m_ma5, m_indicatorColors.get(0),
                        (m_selectShape.equals(m_mainIndicator) &&
                                m_selectShapeEx.equals("5")) ? true : false);
                    drawChartLines(paint, clipRect, 0,
                        m_ma10, m_indicatorColors.get(0),
                        (m_selectShape.equals(m_mainIndicator) &&
                                m_selectShapeEx.equals("10")) ? true : false);
                    drawChartLines(paint, clipRect, 0,
                        m_ma20, m_indicatorColors.get(2),
                        (m_selectShape.equals(m_mainIndicator) &&
                                m_selectShapeEx.equals("20")) ? true : false);
                    drawChartLines(paint, clipRect, 0,
                        m_ma30, m_indicatorColors.get(5),
                        (m_selectShape.equals(m_mainIndicator) &&
                                m_selectShapeEx.equals("30")) ? true : false);
                    drawChartLines(paint, clipRect, 0,
                        m_ma120, m_indicatorColors.get(4),
                        (m_selectShape.equals(m_mainIndicator) &&
                                m_selectShapeEx.equals("120")) ? true : false);
                    drawChartLines(paint, clipRect, 0,
                        m_ma250, m_indicatorColors.get(3),
                        (m_selectShape.equals(m_mainIndicator) &&
                                m_selectShapeEx.equals("250")) ? true : false);
                }
                paint.setClip(clipRect);
            }
            if (indHeight > 0 || indHeight2 > 0)
            {
                for (int d = 2; d <= 3; d++)
                {
                    String sind = m_showIndicator;
                    if (d == 3)
                    {
                        sind = m_showIndicator2;
                        if (indHeight2 <= 0)
                        {
                            continue;
                        }
                    }
                    else
                    {
                        if (indHeight <= 0)
                        {
                            continue;
                        }
                    }
                    if (sind.equals("MACD"))
                    {
                        int zeroY = getChartY(d, 0);
                        paint.drawLine(m_indicatorColors.get(4), m_lineWidthChart, 0,
                            m_leftVScaleWidth, zeroY, getChartX(m_lastVisibleIndex), zeroY);
                        for (int i = m_firstVisibleIndex; i <= lastValidIndex; i++)
                        {
                            int x = getChartX(i);
                            double macd = m_allmacdarr.get(i);
                            int macdY = getChartY(d, macd);
                            if (macdY < zeroY)
                            {
                                paint.drawLine(m_indicatorColors.get(3), m_lineWidthChart, 0, x,
                                    macdY, x, zeroY);
                            }
                            else
                            {
                                paint.drawLine(m_indicatorColors.get(4), m_lineWidthChart, 0, x,
                                    macdY, x, zeroY);
                            }
                            if (m_selectShape.equals(sind) &&
                                m_selectShapeEx.equals("MACD") )
                            {
                                int kPInterval = maxVisibleRecord / 30;
                                if (kPInterval < 2)
                                {
                                    kPInterval = 3;
                                }
                                if (i % kPInterval == 0)
                                {
                                    paint.fillRect(
                                        m_indicatorColors.get(4), x - 3, macdY - 3, x + 3, macdY + 3);
                                }
                            }
                        }
                        drawChartLines(paint, clipRect, d,
                            m_alldifarr, m_indicatorColors.get(0),
                            (m_selectShape.equals(sind) &&
                                    m_selectShapeEx.equals("DIF")) ? true : false);
                        drawChartLines(paint, clipRect, d,
                            m_alldeaarr, m_indicatorColors.get(0),
                            (m_selectShape.equals(sind) &&
                                    m_selectShapeEx.equals("DEA")) ? true : false);
                    }
                    else if (sind.equals("KDJ"))
                    {
                        drawChartLines(paint, clipRect, d,
                            m_kdjK, m_indicatorColors.get(0),
                            (m_selectShape.equals(sind) &&
                                    m_selectShapeEx.equals("K")) ? true : false);
                        drawChartLines(paint, clipRect, d,
                            m_kdjD, m_indicatorColors.get(1),
                            (m_selectShape.equals(sind) &&
                                    m_selectShapeEx.equals("D")) ? true : false);
                        drawChartLines(paint, clipRect, d,
                            m_kdjJ, m_indicatorColors.get(2),
                            (m_selectShape.equals(sind) &&
                                    m_selectShapeEx.equals("J")) ? true : false);
                    }
                    else if (sind.equals("RSI"))
                    {
                        drawChartLines(paint, clipRect, d,
                            m_rsi1, m_indicatorColors.get(5),
                            (m_selectShape.equals(sind) &&
                                    m_selectShapeEx.equals("6")) ? true : false);
                        drawChartLines(paint, clipRect, d,
                            m_rsi2, m_indicatorColors.get(1),
                            (m_selectShape.equals(sind) &&
                                    m_selectShapeEx.equals("12")) ? true : false);
                        drawChartLines(paint, clipRect, d,
                            m_rsi3, m_indicatorColors.get(2),
                            (m_selectShape.equals(sind) &&
                                    m_selectShapeEx.equals("24")) ? true : false);
                    }
                    else if (sind.equals("BIAS"))
                    {
                        drawChartLines(paint, clipRect, d,
                            m_bias1, m_indicatorColors.get(5),
                            (m_selectShape.equals(sind) &&
                                    m_selectShapeEx.equals("1")) ? true : false);
                        drawChartLines(paint, clipRect, d,
                            m_bias2, m_indicatorColors.get(1),
                            (m_selectShape.equals(sind) &&
                                    m_selectShapeEx.equals("2")) ? true : false);
                        drawChartLines(
                            paint, clipRect, d, m_bias3,
                            m_indicatorColors.get(2),
                            (m_selectShape.equals(sind) &&
                                    m_selectShapeEx.equals("3")) ? true : false);
                    }
                    else if (sind.equals("ROC"))
                    {
                        drawChartLines(paint, clipRect, d,
                            m_roc, m_indicatorColors.get(0),
                            (m_selectShape.equals(sind) &&
                                    m_selectShapeEx.equals("ROC")) ? true : false);
                        drawChartLines(paint, clipRect, d,
                            m_rocMa, m_indicatorColors.get(1),
                            (m_selectShape.equals(sind) &&
                                    m_selectShapeEx.equals("ROCMA")) ? true : false);
                    }
                    else if (sind.equals("WR"))
                    {
                        drawChartLines(paint, clipRect, d,
                            m_wr1, m_indicatorColors.get(0),
                            (m_selectShape.equals(sind) &&
                                    m_selectShapeEx.equals("1")) ? true : false);
                        drawChartLines(paint, clipRect, d,
                            m_wr2, m_indicatorColors.get(1),
                            (m_selectShape.equals(sind) &&
                                    m_selectShapeEx.equals("2")) ? true : false);
                    }
                    else if (sind.equals("CCI"))
                    {
                        drawChartLines(paint, clipRect, d,
                            m_cci, m_indicatorColors.get(0),
                            (m_selectShape.equals(sind)) ? true : false);
                    }
                    else if (sind.equals("BBI"))
                    {
                        drawChartLines(paint, clipRect, d,
                            m_bbi, m_indicatorColors.get(0),
                            (m_selectShape.equals(sind)) ? true : false);
                    }
                    else if (sind.equals("TRIX"))
                    {
                        drawChartLines(paint, clipRect, d,
                            m_trix, m_indicatorColors.get(0),
                            (m_selectShape.equals(sind) &&
                                    m_selectShapeEx.equals("TRIX")) ? true : false);
                        drawChartLines(paint, clipRect, d,
                            m_trixMa, m_indicatorColors.get(1),
                            (m_selectShape.equals(sind) &&
                                    m_selectShapeEx.equals("TRIXMA")) ? true : false);
                    }
                    else if (sind.equals("DMA"))
                    {
                        drawChartLines(paint, clipRect, d, m_dma1, m_indicatorColors.get(0),
                            (m_selectShape.equals(sind) && m_selectShapeEx == "DIF") ? true : false);
                        drawChartLines(paint, clipRect, d, m_dma2, m_indicatorColors.get(1),
                            (m_selectShape.equals(sind) && m_selectShapeEx == "DIFMA") ? true : false);
                    }
                }
            }
        }
        //绘制扩展线条
        if (m_shapes.size() > 0)
        {
            for (int i = 0; i < m_shapes.size(); i++)
            {
                BaseShape shape = m_shapes.get(i);
                if (shape.m_shapeType.equals("bar"))
                {
                    for (int j = m_firstVisibleIndex; j <= lastValidIndex; j++)
                    {
                        if (shape.m_showHideDatas.size() > j &&
                          shape.m_showHideDatas.get(j).toString().equals("0"))
                        {
                            continue;
                        }
                        int x = getChartX(j);
                        int y1 = 0;
                        if (shape.m_leftOrRight)
                        {
                            y1 = getChartY(shape.m_divIndex, shape.m_datas.get(j));
                        }
                        else
                        {
                            y1 = getChartYInRight(shape.m_divIndex, shape.m_datas.get(j));
                        }
                        if (!(shape.m_style.equals("2color")))
                        {
                            int y2 = 0;
                            if (shape.m_leftOrRight)
                            {
                                y2 = getChartY(shape.m_divIndex, shape.m_datas2.get(j));
                            }
                            else
                            {
                                y2 = getChartYInRight(shape.m_divIndex, shape.m_datas2.get(j));
                            }
                            if (y1 >= y2)
                            {
                                paint.fillRect(shape.m_color, x - cWidth, y2, x + cWidth, y1);
                            }
                            else
                            {
                                paint.fillRect(shape.m_color, x - cWidth, y1, x + cWidth, y2);
                            }
                        }
                        else
                        {
                            int y2 = 0;
                            if (shape.m_leftOrRight)
                            {
                                y2 = getChartY(shape.m_divIndex, 0);
                            }
                            else
                            {
                                y2 = getChartYInRight(shape.m_divIndex, 0);
                            }
                            if (y1 >= y2)
                            {
                                paint.drawLine(shape.m_color2, 1, 0, x, y1, x, y2);
                            }
                            else
                            {
                                paint.drawLine(shape.m_color, 1, 0, x, y1, x, y2);
                            }
                            if (j == lastValidIndex)
                            {
                                paint.drawLine(shape.m_color2, 1, 0, m_leftVScaleWidth, y2,
                                    size.cx - m_rightVScaleWidth, y2);
                            }
                        }
                    }
                }
                else if (shape.m_shapeType.equals("text"))
                {
                    for (int j = m_firstVisibleIndex; j <= lastValidIndex; j++)
                    {
                        int x = getChartX(j);
                        if (shape.m_datas.get(j) != 0)
                        {
                            int y1 = 0;
                            if (shape.m_leftOrRight)
                            {
                                y1 = getChartY(shape.m_divIndex, shape.m_value);
                            }
                            else
                            {
                                y1 = getChartYInRight(shape.m_divIndex, shape.m_value);
                            }
                            String drawText = shape.m_text;
                            FCSize tSize = paint.textSize(drawText, getFont());
                            paint.drawText(drawText, shape.m_color, getFont(),
                                new FCRect(x - tSize.cx / 2, y1 - tSize.cy / 2, x + tSize.cx / 2, y1 + tSize.cy / 2));
                        }
                    }
                }
                else
                {
                    if (shape.m_leftOrRight)
                    {
                        drawChartLines(paint, clipRect, shape.m_divIndex,
                            shape.m_datas, shape.m_color,
                            (m_selectShape.equals(shape.m_shapeName)) ? true : false);
                    }
                    else
                    {
                        drawChartLinesInRight(paint, clipRect, shape.m_divIndex,
                            shape.m_datas, shape.m_color,
                            (m_selectShape.equals(shape.m_shapeName)) ? true : false);
                    }
                }
            }
        }
    }
    
    /**
     * 绘制十字线
     * @params paint 绘图对象
     * @params clipRect 裁剪区
     */
    public void drawChartCrossLine(FCPaint paint, FCRect clipRect)
    {
        if (m_datas == null || m_datas.size() == 0)
        {
            return;
        }
        FCSize size = getSize();
        int candleDivHeight = getCandleDivHeight();
        int volDivHeight = getVolDivHeight();
        int indDivHeight = getIndDivHeight();
        int indDivHeight2 = getIndDivHeight2();
        int crossLineIndex = m_crossStopIndex;
        if (crossLineIndex == -1 || !m_showCrossLine)
        {
            if (m_lastValidIndex != -1)
            {
                crossLineIndex = m_lastValidIndex;
            }
            else
            {
                crossLineIndex = m_lastVisibleIndex;
            }
        }
        if (crossLineIndex == -1)
        {
            return;
        }
        if (volDivHeight > 0)
        {
            ArrayList<String> drawTitles = new ArrayList<String>();
            ArrayList<Long> drawColors = new ArrayList<Long>();
            drawTitles.add("VOL ".toString() +
                FCTran.getValueByDigit(m_datas.get(crossLineIndex).m_volume / m_magnitude, m_volDigit));
            drawColors.add(getTextColor());
            if (m_shapes.size() > 0)
            {
                for (int i = 0; i < m_shapes.size(); i++)
                {
                    BaseShape shape = m_shapes.get(i);
                    if (shape.m_divIndex == 1)
                    {
                        if (shape.m_title.length() > 0)
                        {
                            if (shape.m_shapeType.equals("bar") && shape.m_style.equals("2color"))
                            {
                                drawTitles.add(shape.m_title +
                                    " ".toString() +
                                    FCTran.getValueByDigit(shape.m_datas.get(crossLineIndex), m_volDigit));
                                drawColors.add(shape.m_color2);
                            }
                            else
                            {
                                if (!(shape.m_shapeType.equals("text")))
                                {
                                    drawTitles.add(shape.m_title +
                                        " ".toString() +
                                        FCTran.getValueByDigit(shape.m_datas.get(crossLineIndex), m_volDigit));
                                    drawColors.add(shape.m_color);
                                    if (shape.m_datas2.size() > 0)
                                    {
                                        drawTitles.add(shape.m_title2 +
                                            " ".toString() +
                                            FCTran.getValueByDigit(shape.m_datas2.get(crossLineIndex), m_volDigit));
                                        drawColors.add(shape.m_color2);
                                    }
                                }
                            }
                        }
                    }
                }
            }
            int iLeft = m_leftVScaleWidth + 5;
            for (int i = 0; i < drawTitles.size(); i++)
            {
                FCSize tSize = paint.textSize(drawTitles.get(i), getFont());
                paint.drawText(
                    drawTitles.get(i), drawColors.get(i), getFont(), new FCRect(iLeft, candleDivHeight + 5, iLeft + tSize.cx, candleDivHeight + 5 + tSize.cy));
                iLeft += tSize.cx + 5;
            }
        }
        //上面显示数据  高开低收
        if (m_cycle.equals("trend"))
        {
            ArrayList<String> drawTitles = new ArrayList<String>();
            ArrayList<Long> drawColors = new ArrayList<Long>();
            if (m_text.length() > 0)
            {
                drawTitles.add(m_text);
                drawColors.add(getTextColor());
            }
            if (m_shapes.size() > 0)
            {
                for (int i = 0; i < m_shapes.size(); i++)
                {
                    BaseShape shape = m_shapes.get(i);
                    if (shape.m_divIndex == 0)
                    {
                        if (shape.m_title.length() > 0)
                        {
                            if (shape.m_shapeType.equals("bar") && shape.m_style.equals("2color"))
                            {
                                drawTitles.add(shape.m_title +
                                    " ".toString() +
                                    FCTran.getValueByDigit(shape.m_datas.get(crossLineIndex), m_candleDigit));
                                drawColors.add(shape.m_color2);
                            }
                            else
                            {
                                if (!(shape.m_shapeType.equals("text")))
                                {
                                    drawTitles.add(shape.m_title +
                                        " ".toString() +
                                        FCTran.getValueByDigit(shape.m_datas.get(crossLineIndex), m_candleDigit));
                                    drawColors.add(shape.m_color);
                                    if (shape.m_datas2.size() > 0)
                                    {
                                        drawTitles.add(shape.m_title2 +
                                            " ".toString() +
                                            FCTran.getValueByDigit(shape.m_datas2.get(crossLineIndex), m_candleDigit));
                                        drawColors.add(shape.m_color2);
                                    }
                                }
                            }
                        }
                    }
                }
            }
            int iLeft = m_leftVScaleWidth + 5;
            for (int i = 0; i < drawTitles.size(); i++)
            {
                FCSize tSize = paint.textSize(drawTitles.get(i), getFont());
                paint.drawText(drawTitles.get(i), drawColors.get(i), getFont(), new FCRect(iLeft, 5, iLeft + tSize.cx, 5 + tSize.cy));
                iLeft += tSize.cx + 5;
            }
        }
        else
        {
            ArrayList<String> drawTitles = new ArrayList<String>();
            ArrayList<Long> drawColors = new ArrayList<Long>();
            if (m_text.length() > 0)
            {
                drawTitles.add(m_text);
                drawColors.add(getTextColor());
            }
            if (m_mainIndicator.equals("MA"))
            {
                if (m_ma5.size() > 0)
                {
                    drawTitles.add("MA5 ".toString() +
                        FCTran.getValueByDigit(m_ma5.get(crossLineIndex), m_candleDigit));
                }
                else
                {
                    drawTitles.add("MA5");
                }
                drawColors.add(m_indicatorColors.get(0));
                if (m_ma10.size() > 0)
                {
                    drawTitles.add("MA10 ".toString() +
                        FCTran.getValueByDigit(m_ma10.get(crossLineIndex), m_candleDigit));
                }
                else
                {
                    drawTitles.add("MA10");
                }
                drawColors.add(m_indicatorColors.get(1));
                if (m_ma20.size() > 0)
                {
                    drawTitles.add("MA20 ".toString() +
                        FCTran.getValueByDigit(m_ma20.get(crossLineIndex), m_candleDigit));
                }
                else
                {
                    drawTitles.add("MA20");
                }
                drawColors.add(m_indicatorColors.get(2));
                if (m_ma30.size() > 0)
                {
                    drawTitles.add("MA30 ".toString() +
                        FCTran.getValueByDigit(m_ma30.get(crossLineIndex), m_candleDigit));
                }
                else
                {
                    drawTitles.add("MA30");
                }
                drawColors.add(m_indicatorColors.get(5));
                if (m_ma120.size() > 0)
                {
                    drawTitles.add("MA120 ".toString() +
                        FCTran.getValueByDigit(m_ma120.get(crossLineIndex), m_candleDigit));
                }
                else
                {
                    drawTitles.add("MA120");
                }
                drawColors.add(m_indicatorColors.get(4));
                if (m_ma250.size() > 0)
                {
                    drawTitles.add("MA250 ".toString() +
                        FCTran.getValueByDigit(m_ma250.get(crossLineIndex), m_candleDigit));
                }
                else
                {
                    drawTitles.add("MA250");
                }
                drawColors.add(m_indicatorColors.get(3));
            }
            else if (m_mainIndicator.equals("BOLL"))
            {
                if (m_bollMid.size() > 0)
                {
                    drawTitles.add("MID ".toString() +
                        FCTran.getValueByDigit(m_bollMid.get(crossLineIndex), m_candleDigit));
                }
                else
                {
                    drawTitles.add("MID");
                }
                drawColors.add(m_indicatorColors.get(0));
                if (m_bollUp.size() > 0)
                {
                    drawTitles.add("UP ".toString() +
                        FCTran.getValueByDigit(m_bollUp.get(crossLineIndex), m_candleDigit));
                }
                else
                {
                    drawTitles.add("UP");
                }
                drawColors.add(m_indicatorColors.get(1));
                if (m_bollDown.size() > 0)
                {
                    drawTitles.add("LOW ".toString() +
                        FCTran.getValueByDigit(m_bollDown.get(crossLineIndex), m_candleDigit));
                }
                else
                {
                    drawTitles.add("LOW");
                }
                drawColors.add(m_indicatorColors.get(2));
            }
            if (m_shapes.size() > 0)
            {
                for (int i = 0; i < m_shapes.size(); i++)
                {
                    BaseShape shape = m_shapes.get(i);
                    if (shape.m_divIndex == 0)
                    {
                        if (shape.m_title.length() > 0)
                        {
                            if (shape.m_shapeType.equals("bar") && shape.m_style.equals("2color"))
                            {
                                drawTitles.add(shape.m_title +
                                    " ".toString() +
                                    FCTran.getValueByDigit(shape.m_datas.get(crossLineIndex), m_candleDigit));
                                drawColors.add(shape.m_color2);
                            }
                            else
                            {
                                if (!(shape.m_shapeType.equals("text")))
                                {
                                    drawTitles.add(shape.m_title +
                                        " ".toString() +
                                        FCTran.getValueByDigit(shape.m_datas.get(crossLineIndex)
                                            , m_candleDigit));
                                    drawColors.add(shape.m_color);
                                    if (shape.m_datas2.size() > 0)
                                    {
                                        drawTitles.add(shape.m_title2 +
                                            " ".toString() +
                                            FCTran.getValueByDigit(shape.m_datas2.get(crossLineIndex)
                                                , m_candleDigit));
                                        drawColors.add(shape.m_color2);
                                    }
                                }
                            }
                        }
                    }
                }
            }
            int iLeft = m_leftVScaleWidth + 5;
            for (int i = 0; i < drawTitles.size(); i++)
            {
                FCSize tSize = paint.textSize(drawTitles.get(i), getFont());
                paint.drawText(drawTitles.get(i), drawColors.get(i), getFont(), new FCRect(iLeft, 5, iLeft + tSize.cx, 5 + tSize.cy));
                iLeft += tSize.cx + 5;
            }
        }
        if (indDivHeight > 0)
        {
            ArrayList<String> drawTitles = new ArrayList<String>();
            ArrayList<Long> drawColors = new ArrayList<Long>();
            if (m_showIndicator.equals("MACD"))
            {
                if (m_alldifarr.size() > 0)
                {
                    drawTitles.add("DIF ".toString() +
                        FCTran.getValueByDigit(m_alldifarr.get(crossLineIndex), m_indDigit));
                }
                else
                {
                    drawTitles.add("DIF");
                }
                drawColors.add(m_indicatorColors.get(0));
                if (m_alldeaarr.size() > 0)
                {
                    drawTitles.add("DEA ".toString() +
                        FCTran.getValueByDigit(m_alldeaarr.get(crossLineIndex), m_indDigit));
                }
                else
                {
                    drawTitles.add("DEA");
                }
                drawColors.add(m_indicatorColors.get(1));
                if (m_allmacdarr.size() > 0)
                {
                    drawTitles.add("MACD ".toString() +
                        FCTran.getValueByDigit(m_allmacdarr.get(crossLineIndex), m_indDigit));
                }
                else
                {
                    drawTitles.add("MACD");
                }
                drawColors.add(m_indicatorColors.get(4));
            }
            else if (m_showIndicator.equals("KDJ"))
            {
                if (m_kdjK.size() > 0)
                {
                    drawTitles.add("K ".toString() +
                        FCTran.getValueByDigit(m_kdjK.get(crossLineIndex), m_indDigit));
                }
                else
                {
                    drawTitles.add("K");
                }
                drawColors.add(m_indicatorColors.get(0));
                if (m_kdjD.size() > 0)
                {
                    drawTitles.add("D ".toString() +
                        FCTran.getValueByDigit(m_kdjD.get(crossLineIndex), m_indDigit));
                }
                else
                {
                    drawTitles.add("D");
                }
                drawColors.add(m_indicatorColors.get(1));
                if (m_kdjJ.size() > 0)
                {
                    drawTitles.add("J ".toString() +
                        FCTran.getValueByDigit(m_kdjJ.get(crossLineIndex), m_indDigit));
                }
                else
                {
                    drawTitles.add("J");
                }
                drawColors.add(m_indicatorColors.get(2));
            }
            else if (m_showIndicator.equals("RSI"))
            {
                if (m_rsi1.size() > 0)
                {
                    drawTitles.add("RSI6 ".toString() +
                        FCTran.getValueByDigit(m_rsi1.get(crossLineIndex), m_indDigit));
                }
                else
                {
                    drawTitles.add("RSI6");
                }
                drawColors.add(m_indicatorColors.get(5));
                if (m_rsi2.size() > 0)
                {
                    drawTitles.add("RSI12 ".toString() +
                        FCTran.getValueByDigit(m_rsi2.get(crossLineIndex), m_indDigit));
                }
                else
                {
                    drawTitles.add("RSI12");
                }
                drawColors.add(m_indicatorColors.get(1));
                if (m_rsi3.size() > 0)
                {
                    drawTitles.add("RSI24 ".toString() +
                        FCTran.getValueByDigit(m_rsi3.get(crossLineIndex), m_indDigit));
                }
                else
                {
                    drawTitles.add("RSI24");
                }
                drawColors.add(m_indicatorColors.get(2));
            }
            else if (m_showIndicator.equals("BIAS"))
            {
                if (m_bias1.size() > 0)
                {
                    drawTitles.add("BIAS6 ".toString() +
                        FCTran.getValueByDigit(m_bias1.get(crossLineIndex), m_indDigit));
                }
                else
                {
                    drawTitles.add("BIAS6");
                }
                drawColors.add(m_indicatorColors.get(5));
                if (m_bias2.size() > 0)
                {
                    drawTitles.add("BIAS12 ".toString() +
                        FCTran.getValueByDigit(m_bias2.get(crossLineIndex), m_indDigit));
                }
                else
                {
                    drawTitles.add("BIAS12");
                }
                drawColors.add(m_indicatorColors.get(1));
                if (m_bias3.size() > 0)
                {
                    drawTitles.add("BIAS24 ".toString() +
                        FCTran.getValueByDigit(m_bias3.get(crossLineIndex), m_indDigit));
                }
                else
                {
                    drawTitles.add("BIAS24");
                }
                drawColors.add(m_indicatorColors.get(2));
            }
            else if (m_showIndicator.equals("ROC"))
            {
                if (m_roc.size() > 0)
                {
                    drawTitles.add("ROC ".toString() +
                        FCTran.getValueByDigit(m_roc.get(crossLineIndex), m_indDigit));
                }
                else
                {
                    drawTitles.add("ROC");
                }
                drawColors.add(m_indicatorColors.get(0));
                if (m_rocMa.size() > 0)
                {
                    drawTitles.add("ROCMA ".toString() +
                        FCTran.getValueByDigit(m_rocMa.get(crossLineIndex), m_indDigit));
                }
                else
                {
                    drawTitles.add("ROCMA");
                }
                drawColors.add(m_indicatorColors.get(1));
            }
            else if (m_showIndicator.equals("WR"))
            {
                if (m_wr1.size() > 0)
                {
                    drawTitles.add("WR5 ".toString() +
                        FCTran.getValueByDigit(m_wr1.get(crossLineIndex), m_indDigit));
                }
                else
                {
                    drawTitles.add("WR5");
                }
                drawColors.add(m_indicatorColors.get(0));
                if (m_wr2.size() > 0)
                {
                    drawTitles.add("WR10 ".toString() +
                        FCTran.getValueByDigit(m_wr2.get(crossLineIndex), m_indDigit));
                }
                else
                {
                    drawTitles.add("WR10");
                }
                drawColors.add(m_indicatorColors.get(1));
            }
            else if (m_showIndicator.equals("CCI"))
            {
                if (m_cci.size() > 0)
                {
                    drawTitles.add("CCI ".toString() +
                        FCTran.getValueByDigit(m_cci.get(crossLineIndex), m_indDigit));
                }
                else
                {
                    drawTitles.add("CCI");
                }
                drawColors.add(m_indicatorColors.get(0));
            }
            else if (m_showIndicator.equals("BBI"))
            {
                if (m_bbi.size() > 0)
                {
                    drawTitles.add("BBI ".toString() +
                        FCTran.getValueByDigit(m_bbi.get(crossLineIndex), m_indDigit));
                }
                else
                {
                    drawTitles.add("BBI");
                }
                drawColors.add(m_indicatorColors.get(0));
            }
            else if (m_showIndicator.equals("TRIX"))
            {
                if (m_trix.size() > 0)
                {
                    drawTitles.add("TRIX ".toString() +
                        FCTran.getValueByDigit(m_trix.get(crossLineIndex), m_indDigit));
                }
                else
                {
                    drawTitles.add("TRIX");
                }
                drawColors.add(m_indicatorColors.get(0));
                if (m_trixMa.size() > 0)
                {
                    drawTitles.add("TRIXMA ".toString() +
                        FCTran.getValueByDigit(m_trixMa.get(crossLineIndex), m_indDigit));
                }
                else
                {
                    drawTitles.add("TRIXMA");
                }
                drawColors.add(m_indicatorColors.get(1));
            }
            else if (m_showIndicator.equals("DMA"))
            {
                if (m_dma1.size() > 0)
                {
                    drawTitles.add("MA10 ".toString() +
                        FCTran.getValueByDigit(m_dma1.get(crossLineIndex), m_indDigit));
                }
                else
                {
                    drawTitles.add("MA10");
                }
                drawColors.add(m_indicatorColors.get(0));
                if (m_dma2.size() > 0)
                {
                    drawTitles.add("MA50 ".toString() +
                        FCTran.getValueByDigit(m_dma2.get(crossLineIndex), m_indDigit));
                }
                else
                {
                    drawTitles.add("MA50");
                }
                drawColors.add(m_indicatorColors.get(1));
            }
            if (m_shapes.size() > 0)
            {
                for (int i = 0; i < m_shapes.size(); i++)
                {
                    BaseShape shape = m_shapes.get(i);
                    if (shape.m_divIndex == 2)
                    {
                        if (shape.m_title.length() > 0)
                        {
                            if (shape.m_shapeType.equals("bar") && shape.m_style.equals("2color"))
                            {
                                drawTitles.add(shape.m_title +
                                    " ".toString() +
                                    FCTran.getValueByDigit(shape.m_datas.get(crossLineIndex), m_indDigit));
                                drawColors.add(shape.m_color2);
                            }
                            else
                            {
                                if (!(shape.m_shapeType.equals("text")))
                                {
                                    drawTitles.add(shape.m_title +
                                        " ".toString() +
                                        FCTran.getValueByDigit(shape.m_datas.get(crossLineIndex)
                                            , m_indDigit));
                                    drawColors.add(shape.m_color);
                                    if (shape.m_datas2.size() > 0)
                                    {
                                        drawTitles.add(shape.m_title2 +
                                            " ".toString() +
                                            FCTran.getValueByDigit(shape.m_datas2.get(crossLineIndex)
                                                , m_indDigit));
                                        drawColors.add(shape.m_color2);
                                    }
                                }
                            }
                        }
                    }
                }
            }
            int iLeft = m_leftVScaleWidth + 5;
            for (int i = 0; i < drawTitles.size(); i++)
            {
                FCSize tSize = paint.textSize(drawTitles.get(i), getFont());
                paint.drawText(drawTitles.get(i), drawColors.get(i), getFont(), new FCRect(iLeft,
                    candleDivHeight + volDivHeight + 5, iLeft + tSize.cx,
                    candleDivHeight + volDivHeight + 5 + tSize.cy));
                iLeft += tSize.cx + 5;
            }
        }
        if (indDivHeight2 > 0)
        {
            ArrayList<String> drawTitles = new ArrayList<String>();
            ArrayList<Long> drawColors = new ArrayList<Long>();
            if (m_showIndicator2.equals("MACD"))
            {
                if (m_alldifarr.size() > 0)
                {
                    drawTitles.add("DIF ".toString() +
                        FCTran.getValueByDigit(m_alldifarr.get(crossLineIndex), m_indDigit));
                }
                else
                {
                    drawTitles.add("DIF");
                }
                drawColors.add(m_indicatorColors.get(0));
                if (m_alldeaarr.size() > 0)
                {
                    drawTitles.add("DEA ".toString() +
                        FCTran.getValueByDigit(m_alldeaarr.get(crossLineIndex), m_indDigit));
                }
                else
                {
                    drawTitles.add("DEA");
                }
                drawColors.add(m_indicatorColors.get(1));
                if (m_allmacdarr.size() > 0)
                {
                    drawTitles.add("MACD ".toString() +
                        FCTran.getValueByDigit(m_allmacdarr.get(crossLineIndex), m_indDigit));
                }
                else
                {
                    drawTitles.add("MACD");
                }
                drawColors.add(m_indicatorColors.get(4));
            }
            else if (m_showIndicator2.equals("KDJ"))
            {
                if (m_kdjK.size() > 0)
                {
                    drawTitles.add("K ".toString() +
                        FCTran.getValueByDigit(m_kdjK.get(crossLineIndex), m_indDigit));
                }
                else
                {
                    drawTitles.add("K");
                }
                drawColors.add(m_indicatorColors.get(0));
                if (m_kdjD.size() > 0)
                {
                    drawTitles.add("D ".toString() +
                        FCTran.getValueByDigit(m_kdjD.get(crossLineIndex), m_indDigit));
                }
                else
                {
                    drawTitles.add("D");
                }
                drawColors.add(m_indicatorColors.get(1));
                if (m_kdjJ.size() > 0)
                {
                    drawTitles.add("J ".toString() +
                        FCTran.getValueByDigit(m_kdjJ.get(crossLineIndex), m_indDigit));
                }
                else
                {
                    drawTitles.add("J");
                }
                drawColors.add(m_indicatorColors.get(2));
            }
            else if (m_showIndicator2.equals("RSI"))
            {
                if (m_rsi1.size() > 0)
                {
                    drawTitles.add("RSI6 ".toString() +
                        FCTran.getValueByDigit(m_rsi1.get(crossLineIndex), m_indDigit));
                }
                else
                {
                    drawTitles.add("RSI6");
                }
                drawColors.add(m_indicatorColors.get(5));
                if (m_rsi2.size() > 0)
                {
                    drawTitles.add("RSI12 ".toString() +
                        FCTran.getValueByDigit(m_rsi2.get(crossLineIndex), m_indDigit));
                }
                else
                {
                    drawTitles.add("RSI12");
                }
                drawColors.add(m_indicatorColors.get(1));
                if (m_rsi3.size() > 0)
                {
                    drawTitles.add("RSI24 ".toString() +
                        FCTran.getValueByDigit(m_rsi3.get(crossLineIndex), m_indDigit));
                }
                else
                {
                    drawTitles.add("RSI24");
                }
                drawColors.add(m_indicatorColors.get(2));
            }
            else if (m_showIndicator2.equals("BIAS"))
            {
                if (m_bias1.size() > 0)
                {
                    drawTitles.add("BIAS6 ".toString() +
                        FCTran.getValueByDigit(m_bias1.get(crossLineIndex), m_indDigit));
                }
                else
                {
                    drawTitles.add("BIAS6");
                }
                drawColors.add(m_indicatorColors.get(5));
                if (m_bias2.size() > 0)
                {
                    drawTitles.add("BIAS12 ".toString() +
                        FCTran.getValueByDigit(m_bias2.get(crossLineIndex), m_indDigit));
                }
                else
                {
                    drawTitles.add("BIAS12");
                }
                drawColors.add(m_indicatorColors.get(1));
                if (m_bias3.size() > 0)
                {
                    drawTitles.add("BIAS24 ".toString() +
                        FCTran.getValueByDigit(m_bias3.get(crossLineIndex), m_indDigit));
                }
                else
                {
                    drawTitles.add("BIAS24");
                }
                drawColors.add(m_indicatorColors.get(2));
            }
            else if (m_showIndicator2.equals("ROC"))
            {
                if (m_roc.size() > 0)
                {
                    drawTitles.add("ROC ".toString() +
                        FCTran.getValueByDigit(m_roc.get(crossLineIndex), m_indDigit));
                }
                else
                {
                    drawTitles.add("ROC");
                }
                drawColors.add(m_indicatorColors.get(0));
                if (m_rocMa.size() > 0)
                {
                    drawTitles.add("ROCMA ".toString() +
                        FCTran.getValueByDigit(m_rocMa.get(crossLineIndex), m_indDigit));
                }
                else
                {
                    drawTitles.add("ROCMA");
                }
                drawColors.add(m_indicatorColors.get(1));
            }
            else if (m_showIndicator2.equals("WR"))
            {
                if (m_wr1.size() > 0)
                {
                    drawTitles.add("WR5 ".toString() +
                        FCTran.getValueByDigit(m_wr1.get(crossLineIndex), m_indDigit));
                }
                else
                {
                    drawTitles.add("WR5");
                }
                drawColors.add(m_indicatorColors.get(0));
                if (m_wr2.size() > 0)
                {
                    drawTitles.add("WR10 ".toString() +
                        FCTran.getValueByDigit(m_wr2.get(crossLineIndex), m_indDigit));
                }
                else
                {
                    drawTitles.add("WR10");
                }
                drawColors.add(m_indicatorColors.get(1));
            }
            else if (m_showIndicator2.equals("CCI"))
            {
                if (m_cci.size() > 0)
                {
                    drawTitles.add("CCI ".toString() +
                        FCTran.getValueByDigit(m_cci.get(crossLineIndex), m_indDigit));
                }
                else
                {
                    drawTitles.add("CCI");
                }
                drawColors.add(m_indicatorColors.get(0));
            }
            else if (m_showIndicator2.equals("BBI"))
            {
                if (m_bbi.size() > 0)
                {
                    drawTitles.add("BBI ".toString() +
                        FCTran.getValueByDigit(m_bbi.get(crossLineIndex), m_indDigit));
                }
                else
                {
                    drawTitles.add("BBI");
                }
                drawColors.add(m_indicatorColors.get(0));
            }
            else if (m_showIndicator2.equals("TRIX"))
            {
                if (m_trix.size() > 0)
                {
                    drawTitles.add("TRIX ".toString() +
                        FCTran.getValueByDigit(m_trix.get(crossLineIndex), m_indDigit));
                }
                else
                {
                    drawTitles.add("TRIX");
                }
                drawColors.add(m_indicatorColors.get(0));
                if (m_trixMa.size() > 0)
                {
                    drawTitles.add("TRIXMA ".toString() +
                        FCTran.getValueByDigit(m_trixMa.get(crossLineIndex), m_indDigit));
                }
                else
                {
                    drawTitles.add("TRIXMA");
                }
                drawColors.add(m_indicatorColors.get(1));
            }
            else if (m_showIndicator2.equals("DMA"))
            {
                if (m_dma1.size() > 0)
                {
                    drawTitles.add("MA10 ".toString() +
                        FCTran.getValueByDigit(m_dma1.get(crossLineIndex), m_indDigit));
                }
                else
                {
                    drawTitles.add("MA10");
                }
                drawColors.add(m_indicatorColors.get(0));
                if (m_dma2.size() > 0)
                {
                    drawTitles.add("MA50 ".toString() +
                        FCTran.getValueByDigit(m_dma2.get(crossLineIndex), m_indDigit));
                }
                else
                {
                    drawTitles.add("MA50");
                }
                drawColors.add(m_indicatorColors.get(1));
            }
            if (m_shapes.size() > 0)
            {
                for (int i = 0; i < m_shapes.size(); i++)
                {
                    BaseShape shape = m_shapes.get(i);
                    if (shape.m_divIndex == 3)
                    {
                        if (shape.m_title.length() > 0)
                        {
                            if (shape.m_shapeType.equals("bar") && shape.m_style.equals("2color"))
                            {
                                drawTitles.add(shape.m_title +
                                    " ".toString() +
                                    FCTran.getValueByDigit(shape.m_datas.get(crossLineIndex), m_indDigit2));
                                drawColors.add(shape.m_color2);
                            }
                            else
                            {
                                if (!(shape.m_shapeType.equals("text")))
                                {
                                    drawTitles.add(shape.m_title +
                                        " ".toString() +
                                        FCTran.getValueByDigit(shape.m_datas.get(crossLineIndex)
                                            , m_indDigit2));
                                    drawColors.add(shape.m_color);
                                    if (shape.m_datas2.size() > 0)
                                    {
                                        drawTitles.add(shape.m_title2 +
                                            " ".toString() +
                                            FCTran.getValueByDigit(shape.m_datas2.get(crossLineIndex)
                                                , m_indDigit2));
                                        drawColors.add(shape.m_color2);
                                    }
                                }
                            }
                        }
                    }
                }
            }
            if (drawTitles.size() > 9)
            {
                int iLeft = m_leftVScaleWidth + 5;
                for (int i = 0; i < drawTitles.size(); i++)
                {
                    FCSize tSize = paint.textSize(drawTitles.get(i), getFont());
                    paint.drawText(drawTitles.get(i), drawColors.get(i), getFont(), new FCRect(iLeft,
                        candleDivHeight + volDivHeight + indDivHeight + 5 + tSize.cy / 2, iLeft + tSize.cx,
                        candleDivHeight + volDivHeight + indDivHeight + 5 + tSize.cy / 2 + tSize.cy));
                    iLeft += tSize.cx + 5;
                }
            }
        }

        if (this == m_native.m_touchMoveView || this == m_native.m_touchDownView)
        {
            String rightText = "";
            if (m_touchPosition.y < candleDivHeight)
            {
                rightText = FCTran.getValueByDigit(getChartValue(m_touchPosition)
                    , m_candleDigit);
            }
            else if (m_touchPosition.y > candleDivHeight &&
                m_touchPosition.y < candleDivHeight + volDivHeight)
            {
                rightText = FCTran.getValueByDigit(getChartValue(m_touchPosition) / m_magnitude
                    , m_volDigit);
            }
            else if (m_touchPosition.y > candleDivHeight + volDivHeight &&
              m_touchPosition.y < candleDivHeight + volDivHeight + indDivHeight)
            {
                rightText = FCTran.getValueByDigit(getChartValue(m_touchPosition)
                    , m_indDigit);
            }
            else if (m_touchPosition.y >
                  candleDivHeight + volDivHeight + indDivHeight &&
              m_touchPosition.y <
                  candleDivHeight + volDivHeight + indDivHeight + indDivHeight2)
            {
                rightText = FCTran.getValueByDigit(getChartValue(m_touchPosition)
                    , m_indDigit2);
            }

            int drawY = m_touchPosition.y;
            if (drawY > size.cy - m_hScaleHeight)
            {
                drawY = size.cy - m_hScaleHeight;
            }
            FCSize tSize = paint.textSize(rightText, getFont());
            if (m_leftVScaleWidth > 0)
            {
                paint.fillRect(m_crossTipColor, m_leftVScaleWidth - tSize.cx, drawY - tSize.cy / 2 - 4,
                    m_leftVScaleWidth, drawY + tSize.cy / 2 + 3);
                paint.drawText(rightText, getTextColor(), getFont(),
                    new FCRect(m_leftVScaleWidth - tSize.cx, drawY - tSize.cy / 2, m_leftVScaleWidth, drawY + tSize.cy / 2));
            }
            if (m_rightVScaleWidth > 0)
            {
                paint.fillRect(m_crossTipColor, size.cx - m_rightVScaleWidth, drawY - tSize.cy / 2 - 4,
                    size.cx - m_rightVScaleWidth + tSize.cx, drawY + tSize.cy / 2 + 3);
                paint.drawText(rightText, getTextColor(), getFont(),
                    new FCRect(size.cx - m_rightVScaleWidth, drawY - tSize.cy / 2, size.cx - m_rightVScaleWidth + tSize.cx, drawY + tSize.cy / 2));
            }
            //绘制十字线
            int drawX = getChartX(m_crossStopIndex);
            if (m_targetOldX == 0 && m_targetOldX2 == 0)
            {
                drawX = m_touchPosition.x;
            }
            if (drawX < m_leftVScaleWidth)
            {
                drawX = m_leftVScaleWidth;
            }
            if (drawX > size.cx - m_rightVScaleWidth)
            {
                drawX = size.cx - m_rightVScaleWidth;
            }
            if (m_showCrossLine)
            {
                paint.drawLine(m_crossLineColor, m_lineWidthChart, 0,
                    m_leftVScaleWidth, drawY, size.cx - m_rightVScaleWidth, drawY);
                paint.drawLine(m_crossLineColor, m_lineWidthChart, 0, drawX, 0,
                    drawX, size.cy - m_hScaleHeight);
            }
            if (m_crossStopIndex != -1 && m_crossStopIndex < m_datas.size())
            {
                double dateNum = m_datas.get(m_crossStopIndex).m_date;
                String xText = FCTran.doubleToStr(dateNum);
                Calendar dt = FCTran.numToDate(dateNum);
                if (m_hScaleFormat.length() > 0)
                {
                    SimpleDateFormat format = new SimpleDateFormat(m_hScaleFormat);
                    xText = format.format(dt.getTime());
                }
                else
                {
                    if (m_cycle.equals("day"))
                    {
                        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
                        xText = format.format(dt.getTime());
                    }
                    else if (m_cycle.equals("minute"))
                    {
                        SimpleDateFormat format = new SimpleDateFormat("HH:mm");
                        xText = format.format(dt.getTime());
                    }
                    else if (m_cycle.equals("trend"))
                    {
                        SimpleDateFormat format = new SimpleDateFormat("HH:mm");
                        xText = format.format(dt.getTime());
                    }
                    else if (m_cycle.equals("second"))
                    {
                        SimpleDateFormat format = new SimpleDateFormat("HH:mm:ss");
                        xText = format.format(dt.getTime());
                    }
                    else if (m_cycle.equals("tick"))
                    {
                        xText = FCTran.intToStr(m_crossStopIndex + 1);
                    }
                }
                FCSize xSize = paint.textSize(xText, getFont());
                paint.fillRect(
                    m_crossTipColor,
                    drawX - xSize.cx / 2 - 2,
                    candleDivHeight + volDivHeight + indDivHeight,
                    drawX + xSize.cx / 2 + 2,
                    candleDivHeight + volDivHeight + indDivHeight + xSize.cy + 6);
                paint.drawText(xText, getTextColor(), getFont(), new FCRect(drawX - xSize.cx / 2,
                    candleDivHeight + volDivHeight + indDivHeight + 3, drawX + xSize.cx / 2,
                    candleDivHeight + volDivHeight + indDivHeight + 3 + xSize.cy));
            }
        }
    }

    /**
     * 绘制刻度
     * @params paint 绘图对象
     * @params clipRect 裁剪区
     */
    public void drawChartScale(FCPaint paint, FCRect clipRect)
    {
        FCSize size = getSize();
        if (m_leftVScaleWidth > 0)
        {
            paint.drawLine(m_scaleColor, m_lineWidthChart, 0,
                m_leftVScaleWidth, 0, m_leftVScaleWidth,
                size.cy - m_hScaleHeight);
        }
        if (m_rightVScaleWidth > 0)
        {
            paint.drawLine(m_scaleColor, m_lineWidthChart, 0,
                size.cx - m_rightVScaleWidth, 0, size.cx - m_rightVScaleWidth,
                size.cy - m_hScaleHeight);
        }
        if (m_hScaleHeight > 0)
        {
            paint.drawLine(m_scaleColor, m_lineWidthChart, 0, 0,
                size.cy - m_hScaleHeight, size.cx, size.cy - m_hScaleHeight);
        }
        int candleDivHeight = getCandleDivHeight();
        int volDivHeight = getVolDivHeight();
        int indDivHeight = getIndDivHeight();
        int indDivHeight2 = getIndDivHeight2();
        if (volDivHeight > 0)
        {
            paint.drawLine(m_scaleColor, m_lineWidthChart, 0,
                m_leftVScaleWidth, candleDivHeight, size.cx - m_rightVScaleWidth, candleDivHeight);
        }
        if (indDivHeight > 0)
        {
            paint.drawLine(m_scaleColor, m_lineWidthChart, 0,
                m_leftVScaleWidth, candleDivHeight + volDivHeight,
                size.cx - m_rightVScaleWidth,
                candleDivHeight + volDivHeight);
        }
        if (indDivHeight2 > 0)
        {
            paint.drawLine(m_scaleColor, m_lineWidthChart, 0,
                m_leftVScaleWidth, candleDivHeight + volDivHeight + indDivHeight,
                size.cx - m_rightVScaleWidth,
                candleDivHeight + volDivHeight + indDivHeight);
        }
        if (m_datas.size() > 0)
        {
            FCPoint topPoint = new FCPoint(0, 20);
            FCPoint bottomPoint = new FCPoint(0, candleDivHeight - 10);
            double candleMax = getChartValue(topPoint);
            double candleMin = getChartValue(bottomPoint);
            chartGridScale(candleMin, candleMax, (candleDivHeight - m_candlePaddingTop - m_candlePaddingBottom) / 2,
                m_vScaleDistance, m_vScaleDistance / 2,
                (candleDivHeight - m_candlePaddingTop - m_candlePaddingBottom) / m_vScaleDistance);
            if (m_gridStep > 0)
            {
                ArrayList<Double> drawValues = new ArrayList<Double>();
                boolean isTrend = m_cycle.equals("trend");
                double firstOpen = m_firstOpen;
                if (isTrend)
                {
                    if (firstOpen == 0)
                    {
                        firstOpen = m_datas.get(m_firstVisibleIndex).m_close;
                    }
                    double subValue = (candleMax - candleMin);
                    int count = (candleDivHeight -
                            m_candlePaddingTop -
                            m_candlePaddingBottom) /
                        m_vScaleDistance;
                    if (count > 0)
                    {
                        subValue /= count;
                    }
                    double start = firstOpen;
                    while (start < candleMax)
                    {
                        start += subValue;
                        if (start <= candleMax)
                        {
                            drawValues.add(start);
                        }
                    }
                    start = firstOpen;
                    while (start > candleMin)
                    {
                        start -= subValue;
                        if (start >= candleMin)
                        {
                            drawValues.add(start);
                        }
                    }
                }
                else
                {
                    double start = 0;
                    if (candleMin >= 0)
                    {
                        while (start + m_gridStep < candleMin)
                        {
                            start += m_gridStep;
                        }
                    }
                    else
                    {
                        while (start - m_gridStep > candleMin)
                        {
                            start -= m_gridStep;
                        }
                    }

                    while (start <= candleMax)
                    {
                        if (start > candleMin)
                        {
                            drawValues.add(start);
                        }
                        start += m_gridStep;
                    }
                }
                drawValues.add(firstOpen);
                for (int i = 0; i < drawValues.size(); i++)
                {
                    double start = drawValues.get(i);
                    int hAxisY = getChartY(0, start);
                    if (hAxisY < 1 || hAxisY > candleDivHeight)
                    {
                        continue;
                    }
                    paint.drawLine(m_gridColor, m_lineWidthChart, 0,
                        m_leftVScaleWidth, hAxisY,
                        size.cx - m_rightVScaleWidth, hAxisY);
                    paint.drawLine(m_scaleColor, m_lineWidthChart, 0,
                        m_leftVScaleWidth - 8, hAxisY, m_leftVScaleWidth, hAxisY);
                    paint.drawLine(m_scaleColor, m_lineWidthChart, 0,
                        size.cx - m_rightVScaleWidth, hAxisY,
                       size.cx - m_rightVScaleWidth + 8, hAxisY);

                    String drawText = FCTran.getValueByDigit(start, m_candleDigit);

                    FCSize tSize = paint.textSize(drawText, getFont());
                    if (isTrend)
                    {
                        double diffRange = ((start - firstOpen) / firstOpen * 100);
                        String diffRangeStr = FCTran.getValueByDigit(diffRange, 2) + "%".toString();
                        FCSize dSize = paint.textSize(diffRangeStr, getFont());
                        if (diffRange >= 0)
                        {
                            paint.drawText(diffRangeStr, m_upColor, getFont(),
                                new FCRect(size.cx - m_rightVScaleWidth + 10,
                                hAxisY - tSize.cy / 2, size.cx - m_rightVScaleWidth + 10 + dSize.cx,
                                hAxisY + tSize.cy / 2));
                        }
                        else
                        {
                            paint.drawText(diffRangeStr, m_downColor, getFont(),
                                new FCRect(size.cx - m_rightVScaleWidth + 10,
                                hAxisY - tSize.cy / 2, size.cx - m_rightVScaleWidth + 10 + dSize.cx,
                                hAxisY + tSize.cy / 2));
                        }
                    }
                    else
                    {
                        if(m_vScaleTextColor != FCColor.None){
                            paint.drawText(drawText, m_vScaleTextColor, getFont(), new FCRect(size.cx - m_rightVScaleWidth + 10,
                                    hAxisY - tSize.cy / 2, size.cx - m_rightVScaleWidth + 10 + tSize.cx,
                                    hAxisY + tSize.cy / 2));
                        }else {
                            paint.drawText(drawText, getTextColor(), getFont(), new FCRect(size.cx - m_rightVScaleWidth + 10,
                                    hAxisY - tSize.cy / 2, size.cx - m_rightVScaleWidth + 10 + tSize.cx,
                                    hAxisY + tSize.cy / 2));
                        }
                    }
                    if(m_vScaleTextColor != FCColor.None){
                        paint.drawText(drawText, m_vScaleTextColor, getFont(),
                                new FCRect(m_leftVScaleWidth - tSize.cx - 10, hAxisY - tSize.cy / 2, m_leftVScaleWidth - 10, hAxisY + tSize.cy / 2));
                    }else {
                        paint.drawText(drawText, getTextColor(), getFont(),
                                new FCRect(m_leftVScaleWidth - tSize.cx - 10, hAxisY - tSize.cy / 2, m_leftVScaleWidth - 10, hAxisY + tSize.cy / 2));
                    }
                }
            }
            topPoint = new FCPoint(0, candleDivHeight + 10);
            bottomPoint = new FCPoint(0, candleDivHeight + volDivHeight - 10);
            double volMax = getChartValue(topPoint);
            double volMin = getChartValue(bottomPoint);
            chartGridScale(volMin, volMax, (volDivHeight - m_volPaddingTop - m_volPaddingBottom) / 2,
                m_vScaleDistance, m_vScaleDistance / 2,
                (volDivHeight - m_volPaddingTop - m_volPaddingBottom) / m_vScaleDistance);
            if (m_gridStep > 0)
            {
                double start = 0;
                if (volMin >= 0)
                {
                    while (start + m_gridStep < volMin)
                    {
                        start += m_gridStep;
                    }
                }
                else
                {
                    while (start - m_gridStep > volMin)
                    {
                        start -= m_gridStep;
                    }
                }
                while (start <= volMax)
                {
                    if (start > volMin)
                    {
                        int hAxisY = getChartY(1, start);
                        if (hAxisY < candleDivHeight ||
                            hAxisY > candleDivHeight + volDivHeight)
                        {
                            start += m_gridStep;
                            continue;
                        }
                        paint.drawLine(m_gridColor, m_lineWidthChart, 0, m_leftVScaleWidth,
                            hAxisY, size.cx - m_rightVScaleWidth, hAxisY);
                        paint.drawLine(m_scaleColor, m_lineWidthChart, 0,
                            m_leftVScaleWidth - 8, hAxisY, m_leftVScaleWidth, hAxisY);
                        paint.drawLine(m_scaleColor, m_lineWidthChart, 0, size.cx - m_rightVScaleWidth,
                            hAxisY, size.cx - m_rightVScaleWidth + 8, hAxisY);
                        String drawText =
                            FCTran.getValueByDigit(start / m_magnitude, m_volDigit);
                        FCSize tSize = paint.textSize(drawText, getFont());
                        if(m_vScaleTextColor != FCColor.None){
                            paint.drawText(drawText, m_vScaleTextColor, getFont(),
                                    new FCRect(size.cx - m_rightVScaleWidth + 10,
                                            hAxisY - tSize.cy / 2, size.cx - m_rightVScaleWidth + 10 + tSize.cx,
                                            hAxisY + tSize.cy / 2));
                            paint.drawText(drawText, m_vScaleTextColor, getFont(),
                                    new FCRect(m_leftVScaleWidth - tSize.cx - 10, hAxisY - tSize.cy / 2, m_leftVScaleWidth - 10, hAxisY + tSize.cy / 2));
                        }else {
                            paint.drawText(drawText, getTextColor(), getFont(),
                                    new FCRect(size.cx - m_rightVScaleWidth + 10,
                                            hAxisY - tSize.cy / 2, size.cx - m_rightVScaleWidth + 10 + tSize.cx,
                                            hAxisY + tSize.cy / 2));
                            paint.drawText(drawText, getTextColor(), getFont(),
                                    new FCRect(m_leftVScaleWidth - tSize.cx - 10, hAxisY - tSize.cy / 2, m_leftVScaleWidth - 10, hAxisY + tSize.cy / 2));
                        }
                    }
                    start += m_gridStep;
                }
            }
            if (indDivHeight > 0)
            {
                topPoint = new FCPoint(0, candleDivHeight + volDivHeight + 10);
                bottomPoint =
                    new FCPoint(0, candleDivHeight + volDivHeight + indDivHeight - 10);
                double indMax = getChartValue(topPoint);
                double indMin = getChartValue(bottomPoint);
                chartGridScale(indMin, indMax, (indDivHeight - m_indPaddingTop - m_indPaddingBottom) / 2,
                    m_vScaleDistance, m_vScaleDistance / 2,
                    (indDivHeight - m_indPaddingTop - m_indPaddingBottom) / m_vScaleDistance);
                if (m_gridStep > 0)
                {
                    double start = 0;
                    if (indMin >= 0)
                    {
                        while (start + m_gridStep < indMin)
                        {
                            start += m_gridStep;
                        }
                    }
                    else
                    {
                        while (start - m_gridStep > indMin)
                        {
                            start -= m_gridStep;
                        }
                    }

                    while (start <= indMax)
                    {
                        if (start > indMin)
                        {
                            int hAxisY = getChartY(2, start);
                            if (hAxisY < candleDivHeight + volDivHeight ||
                                hAxisY > candleDivHeight + volDivHeight + indDivHeight)
                            {
                                start += m_gridStep;
                                continue;
                            }
                            paint.drawLine(m_gridColor, m_lineWidthChart, 0, m_leftVScaleWidth, hAxisY, size.cx - m_rightVScaleWidth, hAxisY);
                            paint.drawLine(m_scaleColor, m_lineWidthChart, 0, m_leftVScaleWidth - 8, hAxisY, m_leftVScaleWidth, hAxisY);
                            paint.drawLine(m_scaleColor, m_lineWidthChart, 0,
                                size.cx - m_rightVScaleWidth, hAxisY, size.cx - m_rightVScaleWidth + 8, hAxisY);
                            String drawText = FCTran.getValueByDigit(start, m_indDigit);
                            FCSize tSize = paint.textSize(drawText, getFont());
                            if(m_vScaleTextColor != FCColor.None){
                                paint.drawText(drawText, m_vScaleTextColor, getFont(),
                                        new FCRect(size.cx - m_rightVScaleWidth + 10,
                                                hAxisY - tSize.cy / 2, size.cx - m_rightVScaleWidth + 10 + tSize.cx,
                                                hAxisY + tSize.cy / 2));
                                paint.drawText(drawText, m_vScaleTextColor, getFont(),
                                        new FCRect(m_leftVScaleWidth - tSize.cx - 10, hAxisY - tSize.cy / 2, m_leftVScaleWidth - 10, hAxisY + tSize.cy / 2));
                            }else {
                                paint.drawText(drawText, getTextColor(), getFont(),
                                        new FCRect(size.cx - m_rightVScaleWidth + 10,
                                                hAxisY - tSize.cy / 2, size.cx - m_rightVScaleWidth + 10 + tSize.cx,
                                                hAxisY + tSize.cy / 2));
                                paint.drawText(drawText, getTextColor(), getFont(),
                                        new FCRect(m_leftVScaleWidth - tSize.cx - 10, hAxisY - tSize.cy / 2, m_leftVScaleWidth - 10, hAxisY + tSize.cy / 2));
                            }
                        }
                        start += m_gridStep;
                    }
                }
            }
            if (indDivHeight2 > 0)
            {
                topPoint = new FCPoint(0, candleDivHeight + volDivHeight + indDivHeight + 10);
                bottomPoint = new FCPoint(0,
                    candleDivHeight + volDivHeight + indDivHeight + indDivHeight2 - 10);
                double indMax2 = getChartValue(topPoint);
                double indMin2 = getChartValue(bottomPoint);
                chartGridScale(indMin2, indMax2, (indDivHeight2 - m_indPaddingTop2 - m_indPaddingBottom2) / 2, m_vScaleDistance, m_vScaleDistance / 2, (indDivHeight2 - m_indPaddingTop2 - m_indPaddingBottom2) /
                        m_vScaleDistance);
                if (m_gridStep > 0)
                {
                    double start = 0;
                    if (indMin2 >= 0)
                    {
                        while (start + m_gridStep < indMin2)
                        {
                            start += m_gridStep;
                        }
                    }
                    else
                    {
                        while (start - m_gridStep > indMin2)
                        {
                            start -= m_gridStep;
                        }
                    }

                    while (start <= indMax2)
                    {
                        if (start > indMin2)
                        {
                            int hAxisY = getChartY(3, start);
                            if (hAxisY < candleDivHeight + volDivHeight + indDivHeight || hAxisY > candleDivHeight + volDivHeight + indDivHeight + indDivHeight2)
                            {
                                start += m_gridStep;
                                continue;
                            }
                            paint.drawLine(m_gridColor, m_lineWidthChart, 0, m_leftVScaleWidth, hAxisY, size.cx - m_rightVScaleWidth, hAxisY);
                            paint.drawLine(m_scaleColor, m_lineWidthChart, 0, m_leftVScaleWidth - 8, hAxisY, m_leftVScaleWidth, hAxisY);
                            paint.drawLine(m_scaleColor, m_lineWidthChart, 0, size.cx - m_rightVScaleWidth, hAxisY, size.cx - m_rightVScaleWidth + 8, hAxisY);
                            String drawText = FCTran.getValueByDigit(start, m_indDigit);
                            FCSize tSize = paint.textSize(drawText, getFont());
                            if(m_vScaleTextColor != FCColor.None){
                                paint.drawText(drawText, m_vScaleTextColor, getFont(), new FCRect(size.cx - m_rightVScaleWidth + 10, hAxisY - tSize.cy / 2, size.cx - m_rightVScaleWidth + 10 + tSize.cx, hAxisY + tSize.cy / 2));
                                paint.drawText(drawText, m_vScaleTextColor, getFont(),
                                        new FCRect(m_leftVScaleWidth - tSize.cx - 10, hAxisY - tSize.cy / 2, m_leftVScaleWidth - 10, hAxisY + tSize.cy / 2));
                            }else {
                                paint.drawText(drawText, getTextColor(), getFont(), new FCRect(size.cx - m_rightVScaleWidth + 10, hAxisY - tSize.cy / 2, size.cx - m_rightVScaleWidth + 10 + tSize.cx, hAxisY + tSize.cy / 2));
                                paint.drawText(drawText, getTextColor(), getFont(),
                                        new FCRect(m_leftVScaleWidth - tSize.cx - 10, hAxisY - tSize.cy / 2, m_leftVScaleWidth - 10, hAxisY + tSize.cy / 2));
                            }
                        }
                        start += m_gridStep;
                    }
                }
            }
        }
        if (m_datas.size() > 0 && m_hScaleHeight > 0)
        {
            double dLeft = m_leftVScaleWidth + 10;
            for (int i = m_firstVisibleIndex; i <= m_lastVisibleIndex; i++)
            {
                double dateNum = m_datas.get(i).m_date;
                String xText = FCTran.doubleToStr(dateNum);
                Calendar dt = FCTran.numToDate(dateNum);
                if (m_hScaleFormat.length() > 0)
                {
                    SimpleDateFormat format = new SimpleDateFormat(m_hScaleFormat);
                    xText = format.format(dt.getTime());
                }
                else
                {
                    if (m_cycle.equals("day"))
                    {
                        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
                        xText = format.format(dt.getTime());
                    }
                    else if (m_cycle.equals("minute"))
                    {
                        SimpleDateFormat format = new SimpleDateFormat("HH:mm");
                        xText = format.format(dt.getTime());
                    }
                    else if (m_cycle.equals("trend"))
                    {
                        SimpleDateFormat format = new SimpleDateFormat("HH:mm");
                        xText = format.format(dt.getTime());
                    }
                    else if (m_cycle.equals("second"))
                    {
                        SimpleDateFormat format = new SimpleDateFormat("HH:mm:ss");
                        xText = format.format(dt.getTime());
                    }
                    else if (m_cycle.equals("tick"))
                    {
                        xText = FCTran.intToStr(m_crossStopIndex + 1);
                    }
                }
                FCSize tSize = paint.textSize(xText, getFont());
                int x = getChartX(i);
                int dx = x - tSize.cx / 2;
                if (dx > dLeft && dx < size.cx - m_rightVScaleWidth - 10)
                {
                    paint.drawLine(m_scaleColor, m_lineWidthChart, 0, x, size.cy - m_hScaleHeight, x, size.cy - m_hScaleHeight + 8);
                    if(m_hScaleTextColor != FCColor.None){
                        paint.drawText(xText, m_hScaleTextColor, getFont(), new FCRect(dx, size.cy - m_hScaleHeight + 8 - tSize.cy / 2 + 7, dx + tSize.cx, size.cy - m_hScaleHeight + 8 + tSize.cy / 2 + 7));
                    }else {
                        paint.drawText(xText, getTextColor(), getFont(), new FCRect(dx, size.cy - m_hScaleHeight + 8 - tSize.cy / 2 + 7, dx + tSize.cx, size.cy - m_hScaleHeight + 8 + tSize.cy / 2 + 7));
                    }
                    i = i + (int)((tSize.cx + m_hScaleTextDistance) / m_hScalePixel) + 1;
                }
            }
        }
    }

    /**
     * 根据三点计算圆心
     * @params x1 横坐标1
     * @params y1 纵坐标1
     * @params x2 横坐标2
     * @params y2 纵坐标2
     * @params x3 横坐标3
     * @params y3 纵坐标3
     */
    public void ellipseOR(double x1, double y1, double x2, double y2, double x3, double y3)
    {
        m_oXChart = ((y3 - y1) * (y2 * y2 - y1 * y1 + x2 * x2 - x1 * x1) +
                (y2 - y1) * (y1 * y1 - y3 * y3 + x1 * x1 - x3 * x3)) /
            (2 * (x2 - x1) * (y3 - y1) - 2 * (x3 - x1) * (y2 - y1));
        m_oYChart = ((x3 - x1) * (x2 * x2 - x1 * x1 + y2 * y2 - y1 * y1) +
                (x2 - x1) * (x1 * x1 - x3 * x3 + y1 * y1 - y3 * y3)) /
            (2 * (y2 - y1) * (x3 - x1) - 2 * (y3 - y1) * (x2 - x1));
        m_rChart = Math.sqrt((x1 - m_oXChart) * (x1 - m_oXChart) + (y1 - m_oYChart) * (y1 - m_oYChart));
    }
    
    /**
     * 判断点是否在椭圆上
     * @params x 横坐标
     * @params y 纵坐标
     * @params oX 坐标起始X
     * @params oY 坐标起始Y
     * @params a 椭圆参数a
     * @params b 椭圆参数b
     */
    public boolean ellipseHasPoint(double x, double y, double oX, double oY, double a, double b)
    {
        x -= oX;
        y -= oY;
        if (a == 0 && b == 0 && x == 0 && y == 0)
        {
            return true;
        }
        if (a == 0)
        {
            if (x == 0 && y >= -b && y <= b)
            {
                return false;
            }
        }
        if (b == 0)
        {
            if (y == 0 && x >= -a && x <= a)
            {
                return true;
            }
        }
        if ((x * x) / (a * a) + (y * y) / (b * b) >= 0.8 &&
            (x * x) / (a * a) + (y * y) / (b * b) <= 1.2)
        {
            return true;
        }
        return false;
    }
    
    /**
     * 计算斐波那契数列
     * @params index 索引
     */
    public int fibonacciValue(int index)
    {
        if (index < 1)
        {
            return 0;
        }
        else
        {
            ArrayList<Integer> vList = new ArrayList<Integer>();
            for (int i = 0; i < index; i++)
            {
                vList.add(0);
            }
            int result = 0;
            for (int i = 0; i <= index - 1; i++)
            {
                if (i == 0 || i == 1)
                {
                    vList.set(i, 1);
                }
                else
                {
                    vList.set(i, vList.get(i - 1) + vList.get(i - 2));
                }
            }
            result = vList.get(index - 1);
            return result;
        }
    }
   
    /**
     * 获取视图类型
     */
    public String getViewType()
    {
        return "Chart";
    }

    /**
     * 获取图表的区域
     * @params plot 画线
     */
    public void getCandleRange(FCPlot plot)
    {
        int bIndex = getChartIndexByDate(plot.m_key1);
        int eIndex = getChartIndexByDate(plot.m_key2);
        int tempBIndex = Math.min(bIndex, eIndex);
        int tempEIndex = Math.max(bIndex, eIndex);
        bIndex = tempBIndex;
        eIndex = tempEIndex;
        ArrayList<Double> highList = new ArrayList<Double>();
        ArrayList<Double> lowList = new ArrayList<Double>();
        for (int i = bIndex; i <= eIndex; i++)
        {
            highList.add(m_datas.get(i).m_high);
            lowList.add(m_datas.get(i).m_low);
        }
        m_nHighChart = maxValue(highList);
        m_nLowChart = minValue(lowList);
    }
   
    /**
     * 计算EMA
     * @params n 周期
     * @params value 当前数据
     * @params lastEMA 上期数据
     */
    public double getEMA(int n, double value, double lastEMA)
    {
        return (value * 2 + lastEMA * (n - 1)) / (n + 1);
    }

    /**
     * 计算MACD
     * @params dif DIF数据
     * @params dea DEA数据
     */
    public ArrayList<Double> getMACD(ArrayList<Double> dif, ArrayList<Double> dea)
    {
        ArrayList<Double> result = new ArrayList<Double>();
        for (int i = 0; i < dif.size(); i++)
        {
            result.add((dif.get(i) - dea.get(i)) * 2);
        }
        return result;
    }

    /**
     * 计算DIF
     * @params close12 12日数据
     * @params close26 26日数据
     */
    public ArrayList<Double> getDIF(ArrayList<Double> close12, ArrayList<Double> close26)
    {
        ArrayList<Double> result = new ArrayList<Double>();
        for (int i = 0; i < close12.size(); i++)
        {
            result.add(close12.get(i) - close26.get(i));
        }
        return result;
    }
    
    /**
     * 根据日期获取索引
     * @params date 日期
     */
    public int getChartIndexByDate(Double date)
    {
        int index = -1;
        for (int i = 0; i < m_datas.size(); i++)
        {
            if (m_datas.get(i).m_date == date)
            {
                index = i;
                break;
            }
        }
        return index;
    }

    /**
     * 获取百分比线的刻度
     * @params y1 纵坐标1
     * @params y2 纵坐标2
     */
    public ArrayList<Integer> getPercentParams(Double y1, Double y2)
    {
        double y0 = 0, y25 = 0, y50 = 0, y75 = 0, y100 = 0;
        y0 = y1;
        y25 = y1 <= y2 ? y1 + (y2 - y1) / 4 : y2 + (y1 - y2) * 3 / 4;
        y50 = y1 <= y2 ? y1 + (y2 - y1) / 2 : y2 + (y1 - y2) / 2;
        y75 = y1 <= y2 ? y1 + (y2 - y1) * 3 / 4 : y2 + (y1 - y2) / 4;
        y100 = y2;
        ArrayList<Integer> list = new ArrayList<Integer>();
        list.add((int)y0);
        list.add((int)y25);
        list.add((int)y50);
        list.add((int)y75);
        list.add((int)y100);
        return list;
    }
    
    /**
     * 获取TRIX的数据
     */
    public void getTRIXData(ArrayList<Double> ticks, int m, ArrayList<Double> trixArr, ArrayList<Double> matrixArr)
    {
        int length = ticks.size();
        ArrayList<Double> mtrArr = new ArrayList<Double>();
        ArrayList<Double> emaArr1 = new ArrayList<Double>();
        emaArr1.add(ticks.get(0));
        for (int i = 1; i < length; i++)
        {
            emaArr1.add(getEMA(m, ticks.get(i), emaArr1.get(i - 1)));
        }

        ArrayList<Double> emaArr2 = new ArrayList<Double>();
        emaArr2.add(emaArr1.get(0));
        for (int i = 1; i < length; i++)
        {
            emaArr2.add(getEMA(m, emaArr1.get(i), emaArr2.get(i - 1)));
        }

        mtrArr.add(emaArr2.get(0));
        for (int i = 1; i < length; i++)
        {
            mtrArr.add(getEMA(m, emaArr2.get(i), mtrArr.get(i - 1)));
        }

        ArrayList<Double> refV = refValue(mtrArr, 1);
        for (int i = 0; i < length; i++)
        {
            double trix = 100 * (mtrArr.get(i) - refV.get(i)) / refV.get(i);
            trixArr.add(trix);
        }

        ArrayList<Double> matrixArrCopy = maValue(trixArr, m);
        for (int i = 0; i < matrixArrCopy.size(); i++)
        {
            matrixArr.add(matrixArrCopy.get(i));
        }
    }

    /**
     * 计算boll指标
     */
    public void getBollData(ArrayList<Double> ticks, int maDays, ArrayList<Double> ups, ArrayList<Double> mas, ArrayList<Double> lows)
    {
        int tickBegin = maDays - 1;
        double maSum = 0;
        double p = 0;
        for (int i = 0; i < ticks.size(); i++)
        {
            double c = ticks.get(i);
            double ma = 0;
            double md = 0;
            int bstart = 0;
            double mdSum = 0;
            maSum = maSum + c;
            if (i >= tickBegin)
            {
                maSum = maSum - p;
                ma = maSum / maDays;
                bstart = i - tickBegin;
                p = ticks.get(bstart);
                mas.add(ma);
                bstart = i - tickBegin;
                p = ticks.get(bstart);
                ArrayList<Double> values = new ArrayList<Double>();
                for (int j = bstart; j < bstart + maDays; j++)
                {
                    values.add(ticks.get(j));
                }
                mdSum = standardDeviationSum(values, ma);
                md = Math.sqrt(mdSum / maDays);
                ups.add(ma + 2 * md);
                lows.add(ma - 2 * md);
            }
            else
            {
                ma = maSum / (i + 1);
                mas.add(ma);
                ArrayList<Double> values = new ArrayList<Double>();
                for (int j = 0; j < i + 1; j++)
                {
                    values.add(ticks.get(j));
                }
                mdSum = standardDeviationSum(values, ma);
                md = Math.sqrt(mdSum / (i + 1));
                ups.add(ma + 2 * md);
                lows.add(ma - 2 * md);
            }
        }
    }
    
    /**
     * 计算kdj指标
     */
    public void getKDJData(ArrayList<Double> highArr, ArrayList<Double> lowArr, ArrayList<Double> closeArr, int n, int m1, int m2, ArrayList<Double> ks, ArrayList<Double> ds, ArrayList<Double> js)
    {
        ArrayList<Double> rsvs = new ArrayList<Double>();
        double lastK = 0;
        double lastD = 0;
        double curK = 0;
        double curD = 0;
        for (int i = 0; i < closeArr.size(); i++)
        {
            ArrayList<Double> highList = new ArrayList<Double>();
            ArrayList<Double> lowList = new ArrayList<Double>();
            int startIndex = i - n;
            if (startIndex < 0)
            {
                startIndex = 0;
            }

            for (int j = startIndex; j <= i; j++)
            {
                highList.add(highArr.get(j));
                lowList.add(lowArr.get(j));
            }

            double close = closeArr.get(i);
            double maxHigh = 0, minLow = 0;
            for (int m = 0; m < highList.size(); m++)
            {
                double high = highList.get(m);
                double low = lowList.get(m);
                if (high > maxHigh)
                {
                    maxHigh = high;
                }
                if (low < minLow)
                {
                    minLow = low;
                }
            }
            if (maxHigh == minLow)
            {
                rsvs.add(0.0);
            }
            else
            {
                rsvs.add(100 * (close - minLow) / (maxHigh - minLow));
            }
            if (i == 0)
            {
                lastK = rsvs.get(i);
                lastD = rsvs.get(i);
            }
            curK = lastK * (m1 - 1) / m1 + 1.0 / m1 * rsvs.get(i);
            ks.add(curK);
            lastK = curK;

            curD = lastD * (m2 - 1) / m2 + 1.0 / m2 * curK;
            ds.add(curD);
            lastD = curD;

            js.add(3.0 * curK - 2.0 * curD);
        }
    }
    
    /**
     * 计算rsi指标
     */
    public void getRSIData(ArrayList<Double> ticks, int n1, int n2, int n3, ArrayList<Double> rsi1, ArrayList<Double> rsi2, ArrayList<Double> rsi3)
    {
        double lastClosePx = ticks.get(0);
        double lastSm1 = 0;
        double lastSa1 = 0;
        double lastSm2 = 0;
        double lastSa2 = 0;
        double lastSm3 = 0;
        double lastSa3 = 0;
        for (int i = 0; i < ticks.size(); i++)
        {
            double c = ticks.get(i);
            double m = Math.max(c - lastClosePx, 0);
            double a = Math.abs(c - lastClosePx);
            if (i == 0)
            {
                lastSm1 = 0;
                lastSa1 = 0;
                rsi1.add(0.0);
            }
            else
            {
                lastSm1 = (m + (n1 - 1) * lastSm1) / n1;
                lastSa1 = (a + (n1 - 1) * lastSa1) / n1;
                if (lastSa1 != 0)
                {
                    rsi1.add(lastSm1 / lastSa1 * 100);
                }
                else
                {
                    rsi1.add(0.0);
                }
            }
            if (i == 0)
            {
                lastSm2 = 0;
                lastSa2 = 0;
                rsi2.add(0.0);
            }
            else
            {
                lastSm2 = (m + (n2 - 1) * lastSm2) / n2;
                lastSa2 = (a + (n2 - 1) * lastSa2) / n2;
                if (lastSa2 != 0)
                {
                    rsi2.add(lastSm2 / lastSa2 * 100);
                }
                else
                {
                    rsi2.add(0.0);
                }
            }
            if (i == 0)
            {
                lastSm3 = 0;
                lastSa3 = 0;
                rsi3.add(0.0);
            }
            else
            {
                lastSm3 = (m + (n3 - 1) * lastSm3) / n3;
                lastSa3 = (a + (n3 - 1) * lastSa3) / n3;
                if (lastSa3 != 0)
                {
                    rsi3.add(lastSm3 / lastSa3 * 100);
                }
                else
                {
                    rsi3.add(0.0);
                }
            }
            lastClosePx = c;
        }
    }

    /**
     * 计算ROC数据
     */
    public void getRocData(ArrayList<Double> ticks, int n, int m, ArrayList<Double> roc, ArrayList<Double> maroc)
    {
        for (int i = 0; i < ticks.size(); i++)
        {
            double currRoc = 0;
            if (i >= n)
            {
                currRoc = 100 * (ticks.get(i) - ticks.get(i - n)) / ticks.get(i - n);
                roc.add(currRoc);
            }
            else
            {
                currRoc = 100 * (ticks.get(i) - ticks.get(0)) / ticks.get(0);
                roc.add(currRoc);
            }
        }
        ArrayList<Double> marocMA = maValue(roc, m);
        for (int i = 0; i < marocMA.size(); i++)
        {
            maroc.add(marocMA.get(i));
        }
    }
    
    /**
     * 获取BIAS的数据
     */
    public void getBIASData(ArrayList<Double> ticks, int n1, int n2, int n3, ArrayList<Double> bias1Arr, ArrayList<Double> bias2Arr, ArrayList<Double> bias3Arr)
    {
        ArrayList<Double> ma1 = maValue(ticks, n1);
        ArrayList<Double> ma2 = maValue(ticks, n2);
        ArrayList<Double> ma3 = maValue(ticks, n3);
        for (int i = 0; i < ticks.size(); i++)
        {
            double b1 = (ticks.get(i) - ma1.get(i)) / ma1.get(i) * 100;
            double b2 = (ticks.get(i) - ma2.get(i)) / ma2.get(i) * 100;
            double b3 = (ticks.get(i) - ma3.get(i)) / ma3.get(i) * 100;
            bias1Arr.add(b1);
            bias2Arr.add(b2);
            bias3Arr.add(b3);
        }
    }
    
    /**
     * 计算DMA（平均差）
     */
    public void getDMAData(ArrayList<Double> ticks, int n1, int n2, ArrayList<Double> difArr, ArrayList<Double> difmaArr)
    {
        ArrayList<Double> ma10 = maValue(ticks, n1);
        ArrayList<Double> ma50 = maValue(ticks, n2);
        for (int i = 0; i < ticks.size(); i++)
        {
            double dif = ma10.get(i) - ma50.get(i);
            difArr.add(dif);
        }
        ArrayList<Double> difma = maValue(difArr, n1);
        for (int i = 0; i < difma.size(); i++)
        {
            difmaArr.add(difma.get(i));
        }
    }

    /**
     * 计算BBI(多空指标)
     */
    public void getBBIData(ArrayList<Double> ticks, int n1, int n2, int n3, int n4, ArrayList<Double> bbiArr)
    {
        ArrayList<Double> ma3 = maValue(ticks, n1);
        ArrayList<Double> ma6 = maValue(ticks, n2);
        ArrayList<Double> ma12 = maValue(ticks, n3);
        ArrayList<Double> ma24 = maValue(ticks, n4);
        for (int i = 0; i < ticks.size(); i++)
        {
            double bbi = (ma3.get(i) + ma6.get(i) + ma12.get(i) + ma24.get(i)) / 4;
            bbiArr.add(bbi);
        }
    }

    /**
     * 计算WR(威廉指标)
     */
    public void getWRData(ArrayList<Double> highArr, ArrayList<Double> lowArr, ArrayList<Double> closeArr, int n1, int n2, ArrayList<Double> wr1Arr, ArrayList<Double> wr2Arr)
    {
        ArrayList<Double> highArr1 = hhvValue(highArr, n1);
        ArrayList<Double> highArr2 = hhvValue(highArr, n2);
        ArrayList<Double> lowArr1 = llvValue(lowArr, n1);
        ArrayList<Double> lowArr2 = llvValue(lowArr, n2);
        for (int i = 0; i < closeArr.size(); i++)
        {
            double high1 = highArr1.get(i);
            double low1 = lowArr1.get(i);
            double high2 = highArr2.get(i);
            double low2 = lowArr2.get(i);
            double close = closeArr.get(i);
            double wr1 = 100 * (high1 - close) / (high1 - low1);
            double wr2 = 100 * (high2 - close) / (high2 - low2);
            wr1Arr.add(wr1);
            wr2Arr.add(wr2);
        }
    }

    /**
     * CCI(顺势指标)计算  CCI（N日）=（TP－MA）÷MD÷0.015
     */
    public void getCCIData(ArrayList<Double> highArr, ArrayList<Double> lowArr, ArrayList<Double> closeArr, int n, ArrayList<Double> cciArr)
    {
        ArrayList<Double> tpArr = new ArrayList<Double>();
        for (int i = 0; i < closeArr.size(); i++)
        {
            tpArr.add((closeArr.get(i) + highArr.get(i) + lowArr.get(i)) / 3);
        }
        ArrayList<Double> maClose = maValue(closeArr, n);

        ArrayList<Double> mdArr = new ArrayList<Double>();
        for (int i = 0; i < closeArr.size(); i++)
        {
            mdArr.add(maClose.get(i) - closeArr.get(i));
        }
        ArrayList<Double> maMD = maValue(mdArr, n);
        for (int i = 0; i < closeArr.size(); i++)
        {
            double cci = 0;
            if (maMD.get(i) > 0)
            {
                cci = (tpArr.get(i) - maClose.get(i)) / (maMD.get(i) * 0.015);
            }
            cciArr.add(cci);
        }
    }
    
    /**
     * 根据索引获取横坐标
     * @params index 索引
     */
    public int getChartX(int index)
    {
        return (int)(m_leftVScaleWidth +
            (index - m_firstVisibleIndex) * m_hScalePixel +
            m_hScalePixel / 2 + m_offsetX);
    }
    
    /**
     * 获取最大显示记录条数
     * @params hScalePixel 间隔
     * @params pureH 横向距离
     */
    public int getChartMaxVisibleCount(double hScalePixel, double pureH)
    {
        int count = (int)(pureH / hScalePixel);
        if (count < 0)
        {
            count = 0;
        }
        return count;
    }
    
    /**
     * 获取图表层的高度
     */
    public int getCandleDivHeight()
    {
        int height = getSize().cy - m_hScaleHeight;
        if (height > 0)
        {
            return (int)(height * m_candleDivPercent);
        }
        else
        {
            return 0;
        }
    }
    
    /**
     * 获取成交量层的高度
     */
    public int getVolDivHeight()
    {
        int height = getSize().cy - m_hScaleHeight;
        if (height > 0)
        {
            return (int)(height * m_volDivPercent);
        }
        else
        {
            return 0;
        }
    }
    
    /**
     * 获取指标层的高度
     */
    public int getIndDivHeight()
    {
        int height = getSize().cy - m_hScaleHeight;
        if (height > 0)
        {
            return (int)(height * m_indDivPercent);
        }
        else
        {
            return 0;
        }
    }

    /**
     * 获取指标层2的高度
     */
    public int getIndDivHeight2()
    {
        int height = getSize().cy - m_hScaleHeight;
        if (height > 0)
        {
            return (int)(height * m_indDivPercent2);
        }
        else
        {
            return 0;
        }
    }
    
    /**
     * 获取横向工作区
     */
    public int getChartWorkAreaWidth()
    {
        return getSize().cx - m_leftVScaleWidth - m_rightVScaleWidth - m_rightSpace - (int)m_offsetX;
    }

    /**
     * 计算线性回归上下限
     * @params plot 画线
     * @params a 直线a
     * @params b 直线b
     */
     public void getLRBandRange(FCPlot plot, double a, double b)
    {
        int bIndex = getChartIndexByDate(plot.m_key1);
        int eIndex = getChartIndexByDate(plot.m_key2);
        int tempBIndex = Math.min(bIndex, eIndex);
        int tempEIndex = Math.max(bIndex, eIndex);
        bIndex = tempBIndex;
        eIndex = tempEIndex;
        ArrayList<Double> upList = new ArrayList<Double>();
        ArrayList<Double> downList = new ArrayList<Double>();
        for (int i = bIndex; i <= eIndex; i++)
        {
            double high = m_datas.get(i).m_high;
            double low = m_datas.get(i).m_low;
            double midValue = (i - bIndex + 1) * a + b;
            upList.add(high - midValue);
            downList.add(midValue - low);
        }
        m_upSubValue = maxValue(upList);
        m_downSubValue = maxValue(downList);
    }

    /**
     * 计算数值在层中的位置
     * @params divIndex 所在层
     * @params value 数值
     */
    public int getChartY(int divIndex, double value)
    {
        if (divIndex == 0)
        {
            if (m_candleMax > m_candleMin)
            {
                double cValue = value, cMax = m_candleMax, cMin = m_candleMin;
                if (!m_vScaleType.equals("standard"))
                {
                    if (cValue > 0)
                    {
                        cValue = Math.log(cValue);
                    }
                    else if (cValue < 0)
                    {
                        cValue = -Math.log(Math.abs(cValue));
                    }
                    if (cMax > 0)
                    {
                        cMax = Math.log(cMax);
                    }
                    else if (cMax < 0)
                    {
                        cMax = -Math.log(Math.abs(cMax));
                    }
                    if (cMin > 0)
                    {
                        cMin = Math.log(cMin);
                    }
                    else if (cMin < 0)
                    {
                        cMin = -Math.log(Math.abs(cMin));
                    }
                }
                double rate = (cValue - cMin) / (cMax - cMin);
                int divHeight = getCandleDivHeight();
                return (int)(divHeight - m_candlePaddingBottom - (divHeight - m_candlePaddingTop - m_candlePaddingBottom) *
                        rate);
            }
            else
            {
                return 0;
            }
        }
        else if (divIndex == 1)
        {
            if (m_volMax > m_volMin)
            {
                double rate = (value - m_volMin) / (m_volMax - m_volMin);
                int candleHeight = getCandleDivHeight();
                int volHeight = getVolDivHeight();
                return (int)(candleHeight + volHeight - m_volPaddingBottom - (volHeight - m_volPaddingTop - m_volPaddingBottom) * rate);
            }
            else
            {
                return 0;
            }
        }
        else if (divIndex == 2)
        {
            if (m_indMax > m_indMin)
            {
                double rate = (value - m_indMin) / (m_indMax - m_indMin);
                int candleHeight = getCandleDivHeight();
                int volHeight = getVolDivHeight();
                int indHeight = getIndDivHeight();
                return (int)(candleHeight + volHeight + indHeight - m_indPaddingBottom - (indHeight - m_indPaddingTop - m_indPaddingBottom) * rate);
            }
            else
            {
                return 0;
            }
        }
        else if (divIndex == 3)
        {
            if (m_indMax2 > m_indMin2)
            {
                double rate = (value - m_indMin2) / (m_indMax2 - m_indMin2);
                int candleHeight = getCandleDivHeight();
                int volHeight = getVolDivHeight();
                int indHeight = getIndDivHeight();
                int indHeight2 = getIndDivHeight2();
                return (int)(candleHeight + volHeight + indHeight + indHeight2 - m_indPaddingBottom2 - (indHeight2 - m_indPaddingTop2 - m_indPaddingBottom2) * rate);
            }
            else
            {
                return 0;
            }
        }
        return 0;
    }

    /**
     * 根据位置计算索引
     * @params mp 坐标
     */
    public int getChartIndex(FCPoint mp)
    {
        if (m_datas.size() == 0)
            {
                return -1;
            }
            if (mp.x <= 0)
            {
                return 0;
            }
            double intX = mp.x - m_leftVScaleWidth - m_hScalePixel - m_offsetX;
            if (intX < 0)
            {
                intX = 0;
            }
            int index = (int)(m_firstVisibleIndex + intX / m_hScalePixel);
            int intPixel = (int)m_hScalePixel;
            if (intPixel > 0 && intX % intPixel != 0)
            {
                index++;
            }
            if (index < 0)
            {
                index = 0;
            }
            else if (index > m_datas.size() - 1)
            {
                index = m_datas.size() - 1;
            }
            return index;
    }
  
    /**
     * 根据索引获取日期
     * @params index 坐标
     */
    public double getChartDateByIndex(int index)
    {
        double date = 0;
        if (index >= 0 && index < m_datas.size())
        {
            date = m_datas.get(index).m_date;
        }
        return date;
    }

    /**
     * 根据坐标获取对应的值
     * @params point 坐标
     */
    public double getChartValue(FCPoint point)
    {
         double candleHeight = getCandleDivHeight();
        double volHeight = getVolDivHeight();
        double indHeight = getIndDivHeight();
        double indHeight2 = getIndDivHeight();
        if (point.y <= candleHeight)
        {
            if (candleHeight - m_candlePaddingTop - m_candlePaddingBottom > 0)
            {
                double rate = (candleHeight - m_candlePaddingBottom - point.y) /
                    (candleHeight - m_candlePaddingTop - m_candlePaddingBottom);
                double cMin = m_candleMin, cMax = m_candleMax;
                if (!(m_vScaleType.equals("standard")))
                {
                    if (cMax > 0)
                    {
                        cMax = Math.log(cMax);
                    }
                    else if (cMax < 0)
                    {
                        cMax = -Math.log(Math.abs(cMax));
                    }
                    if (cMin > 0)
                    {
                        cMin = Math.log(cMin);
                    }
                    else if (cMin < 0)
                    {
                        cMin = -Math.log(Math.abs(cMin));
                    }
                }
                double result = cMin + (cMax - cMin) * rate;
                if (!(m_vScaleType.equals("standard")))
                {
                    return Math.pow(10, result);
                }
                else
                {
                    return result;
                }
            }
        }
        else if (point.y > candleHeight && point.y <= candleHeight + volHeight)
        {
            if (volHeight - m_volPaddingTop - m_volPaddingBottom > 0)
            {
                double rate =
                    (volHeight - m_volPaddingBottom - (point.y - candleHeight)) /
                        (volHeight - m_volPaddingTop - m_volPaddingBottom);
                return m_volMin + (m_volMax - m_volMin) * rate;
            }
        }
        else if (point.y > candleHeight + volHeight &&
          point.y <= candleHeight + volHeight + indHeight)
        {
            if (indHeight - m_indPaddingTop - m_indPaddingBottom > 0)
            {
                double rate = (indHeight -
                        m_indPaddingBottom -
                        (point.y - candleHeight - volHeight)) /
                    (indHeight - m_indPaddingTop - m_indPaddingBottom);
                return m_indMin + (m_indMax - m_indMin) * rate;
            }
        }
        else if (point.y > candleHeight + volHeight + indHeight &&
          point.y <= candleHeight + volHeight + indHeight + indHeight2)
        {
            if (indHeight2 - m_indPaddingTop2 - m_indPaddingBottom2 > 0)
            {
                double rate = (indHeight2 -
                        m_indPaddingBottom2 -
                        (point.y - candleHeight - volHeight - indHeight)) /
                    (indHeight2 - m_indPaddingTop2 - m_indPaddingBottom2);
                return m_indMin2 + (m_indMax2 - m_indMin2) * rate;
            }
        }
        return 0;
    }
    
    /**
     * 计算数值在层中的右轴位置
     * @params divIndex 所在层
     * @params value 数值
     */
    public int getChartYInRight(int divIndex, double value)
    {
        if (divIndex == 0)
        {
            if (m_candleMaxRight > m_candleMinRight)
            {
                double cValue = value,
                    cMax = m_candleMaxRight,
                    cMin = m_candleMinRight;
                if (!(m_vScaleType.equals("standard")))
                {
                    if (cValue > 0)
                    {
                        cValue = Math.log(cValue);
                    }
                    else if (cValue < 0)
                    {
                        cValue = -Math.log(Math.abs(cValue));
                    }
                    if (cMax > 0)
                    {
                        cMax = Math.log(cMax);
                    }
                    else if (cMax < 0)
                    {
                        cMax = -Math.log(Math.abs(cMax));
                    }
                    if (cMin > 0)
                    {
                        cMin = Math.log(cMin);
                    }
                    else if (cMin < 0)
                    {
                        cMin = -Math.log(Math.abs(cMin));
                    }
                }
                double rate = (cValue - cMin) / (cMax - cMin);
                int divHeight = getCandleDivHeight();
                return (int)(divHeight - m_candlePaddingBottom - (divHeight - m_candlePaddingTop - m_candlePaddingBottom) * rate);
            }
            else
            {
                return 0;
            }
        }
        else if (divIndex == 1)
        {
            if (m_volMaxRight > m_volMinRight)
            {
                double rate = (value - m_volMinRight) / (m_volMaxRight - m_volMinRight);
                int candleHeight = getCandleDivHeight();
                int volHeight = getVolDivHeight();
                return (int)(candleHeight + volHeight - m_volPaddingBottom - (volHeight - m_volPaddingTop - m_volPaddingBottom) * rate);
            }
            else
            {
                return 0;
            }
        }
        else if (divIndex == 2)
        {
            if (m_indMaxRight > m_indMinRight)
            {
                double rate = (value - m_indMinRight) / (m_indMaxRight - m_indMinRight);
                int candleHeight = getCandleDivHeight();
                int volHeight = getVolDivHeight();
                int indHeight = getIndDivHeight();
                return (int)(candleHeight + volHeight + indHeight - m_indPaddingBottom - (indHeight - m_indPaddingTop - m_indPaddingBottom) * rate);
            }
            else
            {
                return 0;
            }
        }
        else if (divIndex == 3)
        {
            if (m_indMax2Right > m_indMin2Right)
            {
                double rate = (value - m_indMin2Right) / (m_indMax2Right - m_indMin2Right);
                int candleHeight = getCandleDivHeight();
                int volHeight = getVolDivHeight();
                int indHeight = getIndDivHeight();
                int indHeight2 = getIndDivHeight2();
                return (int)(candleHeight + volHeight + indHeight + indHeight2 - m_indPaddingBottom2 - (indHeight2 - m_indPaddingTop2 - m_indPaddingBottom2) * rate);
            }
            else
            {
                return 0;
            }
        }
        return 0;
    }
    
    /**
     * 根据坐标获取对应的值
     * @params point 坐标
     */
    public double getCandleDivValue(FCPoint point)
    {
        double candleHeight = getCandleDivHeight();
        double rate = 0;
        if (candleHeight - m_candlePaddingTop - m_candlePaddingBottom > 0)
        {
            rate = (candleHeight - m_candlePaddingBottom - point.y) /
                 (candleHeight - m_candlePaddingTop - m_candlePaddingBottom);
        }
        double cMin = m_candleMin, cMax = m_candleMax;
        if (!m_vScaleType.equals("standard"))
        {
            if (cMax > 0)
            {
                cMax = Math.log(cMax);
            }
            else if (cMax < 0)
            {
                cMax = -Math.log(Math.abs(cMax));
            }
            if (cMin > 0)
            {
                cMin = Math.log(cMin);
            }
            else if (cMin < 0)
            {
                cMin = -Math.log(Math.abs(cMin));
            }
        }
        double result = cMin + (cMax - cMin) * rate;
        if (m_vScaleType.equals("standard"))
        {
            return Math.pow(10, result);
        }
        else
        {
            return result;
        }
    }
    
    /**
     * 计算最大值
     * @params ticks 最高价数组
     * @params days 周期
     */
    public ArrayList<Double> hhvValue(ArrayList<Double> ticks, int days)
    {
        ArrayList<Double> hhv = new ArrayList<Double>();
        double max = ticks.get(0);
        for (int i = 0; i < ticks.size(); i++)
        {
            if (i >= days)
            {
                max = ticks.get(i);
                for (int j = i; j > i - days; j--)
                {
                    if (max < ticks.get(j))
                    {
                        max = ticks.get(j);
                    }
                }
                hhv.add(max);
            }
            else
            {
                if (max < ticks.get(i))
                {
                    max = ticks.get(i);
                }
                hhv.add(max);
            }
        }
        return hhv;
    }

    /**
     * 图表的键盘按下事件
     * @params key 按键
     */
    public void keyDownChart(char key)
    {
        if (key == 38)
        {
            zoomOutChart();
        }
        else if (key == 40)
        {
            zoomInChart();
        }
        else if (key == 37)
        {
            scrollLeftChart(1);
        }
        else if (key == 39)
        {
            scrollRightChart(1);
        }
    }

    /**
     * 判断是否选中图形
     * @params mp 坐标
     */
    public void judgeSelectShape(FCPoint mp)
    {
            m_selectShape = "";
            m_selectShapeEx = "";
            double candleHeight = getCandleDivHeight();
            double volHeight = getVolDivHeight();
            double indHeight = getIndDivHeight();
            double indHeight2 = getIndDivHeight2();
            int index = getChartIndex(mp);
            if (mp.y >= candleHeight + volHeight + indHeight &&
                mp.y <= candleHeight + volHeight + indHeight + indHeight2)
            {
                if (m_showIndicator2.equals("MACD"))
                {
                    if (selectLines(mp, 3, m_allmacdarr, index))
                    {
                        m_selectShape = m_showIndicator2;
                        m_selectShapeEx = "MACD";
                    }
                    if (selectLines(mp, 3, m_alldifarr, index))
                    {
                        m_selectShape = m_showIndicator2;
                        m_selectShapeEx = "DIF";
                    }
                    else if (selectLines(mp, 3, m_alldeaarr, index))
                    {
                        m_selectShape = m_showIndicator2;
                        m_selectShapeEx = "DEA";
                    }
                }
                else if (m_showIndicator2.equals("KDJ"))
                {
                    if (selectLines(mp, 3, m_kdjK, index))
                    {
                        m_selectShape = m_showIndicator2;
                        m_selectShapeEx = "K";
                    }
                    else if (selectLines(mp, 3, m_kdjD, index))
                    {
                        m_selectShape = m_showIndicator2;
                        m_selectShapeEx = "D";
                    }
                    else if (selectLines(mp, 3, m_kdjJ, index))
                    {
                        m_selectShape = m_showIndicator2;
                        m_selectShapeEx = "J";
                    }
                }
                else if (m_showIndicator2.equals("RSI"))
                {
                    if (selectLines(mp, 3, m_rsi1, index))
                    {
                        m_selectShape = m_showIndicator2;
                        m_selectShapeEx = "6";
                    }
                    else if (selectLines(mp, 3, m_rsi2, index))
                    {
                        m_selectShape = m_showIndicator2;
                        m_selectShapeEx = "12";
                    }
                    else if (selectLines(mp, 3, m_rsi3, index))
                    {
                        m_selectShape = m_showIndicator2;
                        m_selectShapeEx = "24";
                    }
                }
                else if (m_showIndicator2.equals("BIAS"))
                {
                    if (selectLines(mp, 3, m_bias1, index))
                    {
                        m_selectShape = m_showIndicator2;
                        m_selectShapeEx = "1";
                    }
                    else if (selectLines(mp, 3, m_bias2, index))
                    {
                        m_selectShape = m_showIndicator2;
                        m_selectShapeEx = "2";
                    }
                    else if (selectLines(mp, 3, m_bias3, index))
                    {
                        m_selectShape = m_showIndicator2;
                        m_selectShapeEx = "3";
                    }
                }
                else if (m_showIndicator2.equals("ROC"))
                {
                    if (selectLines(mp, 3, m_roc, index))
                    {
                        m_selectShape = m_showIndicator2;
                        m_selectShapeEx = "ROC";
                    }
                    else if (selectLines(mp, 3, m_rocMa, index))
                    {
                        m_selectShape = m_showIndicator2;
                        m_selectShapeEx = "ROCMA";
                    }
                }
                else if (m_showIndicator2.equals("WR"))
                {
                    if (selectLines(mp, 3, m_wr1, index))
                    {
                        m_selectShape = m_showIndicator2;
                        m_selectShapeEx = "1";
                    }
                    else if (selectLines(mp, 3, m_wr2, index))
                    {
                        m_selectShape = "WR";
                        m_selectShapeEx = "2";
                    }
                }
                else if (m_showIndicator2.equals("CCI"))
                {
                    if (selectLines(mp, 3, m_cci, index))
                    {
                        m_selectShape = m_showIndicator2;
                    }
                }
                else if (m_showIndicator2.equals("BBI"))
                {
                    if (selectLines(mp, 3, m_bbi, index))
                    {
                        m_selectShape = m_showIndicator2;
                    }
                }
                else if (m_showIndicator2.equals("TRIX"))
                {
                    if (selectLines(mp, 3, m_trix, index))
                    {
                        m_selectShape = m_showIndicator2;
                        m_selectShapeEx = "TRIX";
                    }
                    else if (selectLines(mp, 3, m_trixMa, index))
                    {
                        m_selectShape = m_showIndicator2;
                        m_selectShapeEx = "TRIXMA";
                    }
                }
                else if (m_showIndicator2.equals("DMA"))
                {
                    if (selectLines(mp, 3, m_dma1, index))
                    {
                        m_selectShape = m_showIndicator2;
                        m_selectShapeEx = "DIF";
                    }
                    else if (selectLines(mp, 3, m_dma2, index))
                    {
                        m_selectShape = m_showIndicator2;
                        m_selectShapeEx = "DIFMA";
                    }
                }
            }
            else if (mp.y >= candleHeight + volHeight &&
                mp.y <= candleHeight + volHeight + indHeight)
            {
                if (m_showIndicator.equals("MACD"))
                {
                    if (selectLines(mp, 2, m_allmacdarr, index))
                    {
                        m_selectShape = m_showIndicator;
                        m_selectShapeEx = "MACD";
                    }
                    if (selectLines(mp, 2, m_alldifarr, index))
                    {
                        m_selectShape = m_showIndicator;
                        m_selectShapeEx = "DIF";
                    }
                    else if (selectLines(mp, 2, m_alldeaarr, index))
                    {
                        m_selectShape = m_showIndicator;
                        m_selectShapeEx = "DEA";
                    }
                }
                else if (m_showIndicator.equals("KDJ"))
                {
                    if (selectLines(mp, 2, m_kdjK, index))
                    {
                        m_selectShape = m_showIndicator;
                        m_selectShapeEx = "K";
                    }
                    else if (selectLines(mp, 2, m_kdjD, index))
                    {
                        m_selectShape = m_showIndicator;
                        m_selectShapeEx = "D";
                    }
                    else if (selectLines(mp, 2, m_kdjJ, index))
                    {
                        m_selectShape = m_showIndicator;
                        m_selectShapeEx = "J";
                    }
                }
                else if (m_showIndicator.equals("RSI"))
                {
                    if (selectLines(mp, 2, m_rsi1, index))
                    {
                        m_selectShape = m_showIndicator;
                        m_selectShapeEx = "6";
                    }
                    else if (selectLines(mp, 2, m_rsi2, index))
                    {
                        m_selectShape = m_showIndicator;
                        m_selectShapeEx = "12";
                    }
                    else if (selectLines(mp, 2, m_rsi3, index))
                    {
                        m_selectShape = m_showIndicator;
                        m_selectShapeEx = "24";
                    }
                }
                else if (m_showIndicator.equals("BIAS"))
                {
                    if (selectLines(mp, 2, m_bias1, index))
                    {
                        m_selectShape = m_showIndicator;
                        m_selectShapeEx = "1";
                    }
                    else if (selectLines(mp, 2, m_bias2, index))
                    {
                        m_selectShape = m_showIndicator;
                        m_selectShapeEx = "2";
                    }
                    else if (selectLines(mp, 2, m_bias3, index))
                    {
                        m_selectShape = m_showIndicator;
                        m_selectShapeEx = "3";
                    }
                }
                else if (m_showIndicator.equals("ROC"))
                {
                    if (selectLines(mp, 2, m_roc, index))
                    {
                        m_selectShape = m_showIndicator;
                        m_selectShapeEx = "ROC";
                    }
                    else if (selectLines(mp, 2, m_rocMa, index))
                    {
                        m_selectShape = m_showIndicator;
                        m_selectShapeEx = "ROCMA";
                    }
                }
                else if (m_showIndicator.equals("WR"))
                {
                    if (selectLines(mp, 2, m_wr1, index))
                    {
                        m_selectShape = m_showIndicator;
                        m_selectShapeEx = "1";
                    }
                    else if (selectLines(mp, 2, m_wr2, index))
                    {
                        m_selectShape = "WR";
                        m_selectShapeEx = "2";
                    }
                }
                else if (m_showIndicator.equals("CCI"))
                {
                    if (selectLines(mp, 2, m_cci, index))
                    {
                        m_selectShape = m_showIndicator;
                    }
                }
                else if (m_showIndicator.equals("BBI"))
                {
                    if (selectLines(mp, 2, m_bbi, index))
                    {
                        m_selectShape = m_showIndicator;
                    }
                }
                else if (m_showIndicator.equals("TRIX"))
                {
                    if (selectLines(mp, 2, m_trix, index))
                    {
                        m_selectShape = m_showIndicator;
                        m_selectShapeEx = "TRIX";
                    }
                    else if (selectLines(mp, 2, m_trixMa, index))
                    {
                        m_selectShape = m_showIndicator;
                        m_selectShapeEx = "TRIXMA";
                    }
                }
                else if (m_showIndicator.equals("DMA"))
                {
                    if (selectLines(mp, 2, m_dma1, index))
                    {
                        m_selectShape = m_showIndicator;
                        m_selectShapeEx = "DIF";
                    }
                    else if (selectLines(mp, 2, m_dma2, index))
                    {
                        m_selectShape = m_showIndicator;
                        m_selectShapeEx = "DIFMA";
                    }
                }
            }
            else if (mp.y >= candleHeight && mp.y <= candleHeight + volHeight)
            {
                int volY = getChartY(1, m_datas.get(index).m_volume);
                int zeroY = getChartY(1, 0);
                if (mp.y >= Math.min(volY, zeroY) && mp.y <= Math.max(volY, zeroY))
                {
                    m_selectShape = "VOL";
                }
            }
            else if (mp.y >= 0 && mp.y <= candleHeight)
            {
                boolean isTrend = m_cycle.equals("trend");
                if (!isTrend)
                {
                    if (m_mainIndicator.equals("BOLL"))
                    {
                        if (selectLines(mp, 0, m_bollMid, index))
                        {
                            m_selectShape = m_mainIndicator;
                            m_selectShapeEx = "MID";
                        }
                        else if (selectLines(mp, 0, m_bollUp, index))
                        {
                            m_selectShape = m_mainIndicator;
                            m_selectShapeEx = "UP";
                        }
                        else if (selectLines(mp, 0, m_bollDown, index))
                        {
                            m_selectShape = m_mainIndicator;
                            m_selectShapeEx = "DOWN";
                        }
                    }
                    else if (m_mainIndicator.equals("MA"))
                    {
                        if (selectLines(mp, 0, m_ma5, index))
                        {
                            m_selectShape = m_mainIndicator;
                            m_selectShapeEx.equals("5");
                        }
                        else if (selectLines(mp, 0, m_ma10, index))
                        {
                            m_selectShape = m_mainIndicator;
                            m_selectShapeEx.equals("10");
                        }
                        else if (selectLines(mp, 0, m_ma20, index))
                        {
                            m_selectShape = m_mainIndicator;
                            m_selectShapeEx.equals("20");
                        }
                        else if (selectLines(mp, 0, m_ma30, index))
                        {
                            m_selectShape = m_mainIndicator;
                            m_selectShapeEx.equals("30");
                        }
                        else if (selectLines(mp, 0, m_ma120, index))
                        {
                            m_selectShape = m_mainIndicator;
                            m_selectShapeEx.equals("120");
                        }
                        else if (selectLines(mp, 0, m_ma250, index))
                        {
                            m_selectShape = m_mainIndicator;
                            m_selectShapeEx.equals("250");
                        }
                    }
                }
                if (m_selectShape.equals(""))
                {
                    int highY = getChartY(0, m_datas.get(index).m_high);
                    int lowY = getChartY(0, m_datas.get(index).m_low);
                    if (isTrend)
                    {
                        if (selectLines(mp, 0, m_closeArr, index))
                        {
                            m_selectShape = "CANDLE";
                        }
                    }
                    else
                    {
                        if (mp.y >= Math.min(lowY, highY) && mp.y <= Math.max(lowY, highY))
                        {
                            m_selectShape = "CANDLE";
                        }
                    }
                }
            }
            if (m_shapes.size() > 0)
            {
                for (int i = 0; i < m_shapes.size(); i++)
                {
                    BaseShape shape = m_shapes.get(i);
                    if (shape.m_leftOrRight)
                    {
                        if (selectLines(mp, shape.m_divIndex, shape.m_datas, index))
                        {
                            m_selectShape = shape.m_shapeName;
                            break;
                        }
                    }
                    else
                    {
                        if (selectLinesInRight(mp, shape.m_divIndex, shape.m_datas, index))
                        {
                            m_selectShape = shape.m_shapeName;
                            break;
                        }
                    }
                }
            }
    }

    /**
     * 计算直线参数
     * @params x1 横坐标1
     * @params y1 纵坐标1
     * @params x2 横坐标2
     * @params y2 纵坐标2
     * @params x3 横坐标3
     * @params y3 纵坐标3
     */
    public void lineXY(double x1, double y1, double x2, double y2, double oX, double oY)
    {
        m_kChart = 0;
        m_bChart = 0;
        if ((x1 - oX) != (x2 - oX))
        {
            m_kChart = ((y2 - oY) - (y1 - oY)) / ((x2 - oX) - (x1 - oX));
            m_bChart = (y1 - oY) - m_kChart * (x1 - oX);
        }
    }

    /**
     * 计算线性回归
     * @params list 集合
     */
    public double linearRegressionEquation(ArrayList<Double> list)
    {
        double result = 0;
        double sumX = 0;
        double sumY = 0;
        double sumUp = 0;
        double sumDown = 0;
        double xAvg = 0;
        double yAvg = 0;
        m_kChart = 0;
        m_bChart = 0;
        int length = list.size();
        if (length > 1)
        {
            for (int i = 0; i < length; i++)
            {
                sumX += i + 1;
                sumY += list.get(i);
            }
            xAvg = sumX / length;
            yAvg = sumY / length;
            for (int i = 0; i < length; i++)
            {
                sumUp += (i + 1 - xAvg) * (list.get(i) - yAvg);
                sumDown += (i + 1 - xAvg) * (i + 1 - xAvg);
            }
            m_kChart = sumUp / sumDown;
            m_bChart = yAvg - m_kChart * xAvg;
        }
        return result;
    }
    
    /**
     * 计算最小值
     * @params ticks 最高价数组
     * @params days 周期
     */
    public ArrayList<Double> llvValue(ArrayList<Double> ticks, int days)
    {
        ArrayList<Double> llv = new ArrayList<Double>();
        Double min = ticks.get(0);
        for (int i = 0; i < ticks.size(); i++)
        {
            if (i >= days)
            {
                min = ticks.get(i);
                for (int j = i; j > i - days; j--)
                {
                    if (min > ticks.get(j))
                    {
                        min = ticks.get(j);
                    }
                }
                llv.add(min);
            }
            else
            {
                if (min > ticks.get(i))
                {
                    min = ticks.get(i);
                }
                llv.add(min);
            }
        }
        return llv;
    }

    /**
     * 计算最大值
     * @params list 集合
     */
    public double maxValue(ArrayList<Double> list)
    {
        int length = list.size();
        double max = 0;
        for (int i = 0; i < length; i++)
        {
            if (i == 0)
            {
                max = list.get(i);
            }
            else
            {
                if (max < list.get(i))
                {
                    max = list.get(i);
                }
            }
        }
        return max;
    }

    /**
     * 计算最小值
     * @params list 集合
     */
    public double minValue(ArrayList<Double> list)
    {
        int length = list.size();
        double min = 0;
        for (int i = 0; i < length; i++)
        {
            if (i == 0)
            {
                min = list.get(i);
            }
            else
            {
                if (min > list.get(i))
                {
                    min = list.get(i);
                }
            }
        }
        return min;
    }

    /**
     * MA数据计算
     * @params ticks 最高价数组
     * @params days 周期
     */
    public ArrayList<Double> maValue(ArrayList<Double> ticks, int days)
    {
        double maSum = 0;
        ArrayList<Double> mas = new ArrayList<Double>();
        double last = 0;
        for (int i = 0; i < ticks.size(); i++)
        {
            double ma = 0;
            if (i >= days)
            {
                last = ticks.get(i - days);
                maSum = maSum + ticks.get(i) - last;
                ma = maSum / days;
            }
            else
            {
                maSum += ticks.get(i);
                ma = maSum / (i + 1);
            }
            mas.add(ma);
        }
        return mas;
    }

    /**
     * 绘图方法
     * @params paint 绘图对象
     * @params clipRect 裁剪区
     */
    public void onPaint(FCPaint paint, FCRect clipRect)
    {
        super.onPaint(paint, clipRect);
        drawChartScale(paint, clipRect);
        drawChartStock(paint, clipRect);
        drawChartPlot(paint, clipRect);
        drawChartCrossLine(paint, clipRect);
    }
    
    /**
     * 触摸按下方法
     * @params touchInfo 触摸信息
     */
    public void onTouchDown(FCTouchInfo touchInfo)
    {
        super.onTouchDown(touchInfo);
        touchDownChart(touchInfo.m_firstTouch, touchInfo.m_firstPoint, touchInfo.m_secondTouch, touchInfo.m_secondPoint, touchInfo.m_clicks);
        invalidate();
    }

    /**
     * 触摸移动方法
     * @params touchInfo 触摸信息
     */
    public void onTouchMove(FCTouchInfo touchInfo)
    {
        super.onTouchMove(touchInfo);
        touchMoveChart(touchInfo.m_firstTouch, touchInfo.m_firstPoint, touchInfo.m_secondTouch, touchInfo.m_secondPoint);
        invalidate();
    }
    
    /**
     * 触摸离开方法
     * @params touchInfo 触摸信息
     */
    public void onTouchLeave(FCTouchInfo touchInfo)
    {
        super.onTouchLeave(touchInfo);
        invalidate();
    }

    /**
     * 触摸抬起方法
     * @params touchInfo 触摸信息
     */
    public void onTouchUp(FCTouchInfo touchInfo)
    {
        super.onTouchUp(touchInfo);
        m_firstTouchIndexCache = -1;
        m_secondTouchIndexCache = -1;
        invalidate();
    }

    /**
     * 触摸滚动方法
     * @params touchInfo 触摸信息
     */
    public void onTouchWheel(FCTouchInfo touchInfo)
    {
        super.onTouchWheel(touchInfo);
        if (touchInfo.m_delta > 0)
        {
            zoomOutChart();
        }
        else if (touchInfo.m_delta < 0)
        {
            zoomInChart();
        }
        invalidate();
    }

    /**
     * 键盘按下方法
     * @params key 按键
     */
    public void onKeyDown(char key)
    {
        super.onKeyDown(key);
        keyDownChart(key);
        invalidate();
    }

    /**
     * 计算平行四边形参数
     * @params x1 横坐标1
     * @params y1 纵坐标1
     * @params x2 横坐标2
     * @params y2 纵坐标2
     * @params x3 横坐标3
     * @params y3 纵坐标3
     */
    public void parallelogram(double x1, double y1, double x2, double y2, double x3, double y3)
    {
        m_x4Chart = x1 + x3 - x2;
        m_y4Chart = y1 + y3 - y2;
    }
    
    /**
     * 根据坐标计算矩形
     * @params x1 横坐标1
     * @params y1 纵坐标1
     * @params x2 横坐标2
     * @params y2 纵坐标2
     */
    public void rectangleXYWH(double x1, double y1, double x2, double y2)
    {
        m_xChart = x1 < x2 ? x1 : x2;
        m_yChart = y1 < y2 ? y1 : y2;
        m_wChart = x1 - x2 > 0 ? x1 - x2 : x2 - x1;
        m_hChart = y1 - y2 > 0 ? y1 - y2 : y2 - y1;
        if (m_wChart <= 0)
        {
            m_wChart = 4;
        }
        if (m_hChart <= 0)
        {
            m_hChart = 4;
        }
    }
    
    /**
     * 自动设置首先可见和最后可见的记录号
     */
    public void resetChartVisibleRecord()
    {
        int rowsCount = m_datas.size();
        double workingAreaWidth = getChartWorkAreaWidth();
        if (m_autoFillHScale)
        {
            if (workingAreaWidth > 0 && rowsCount > 0)
            {
                m_hScalePixel = workingAreaWidth / rowsCount;
                m_firstVisibleIndex = 0;
                m_lastVisibleIndex = rowsCount - 1;
            }
        }
        else
        {
            int maxVisibleRecord =
                getChartMaxVisibleCount(m_hScalePixel, workingAreaWidth);
            //没数据时重置
            if (rowsCount == 0)
            {
                m_firstVisibleIndex = -1;
                m_lastVisibleIndex = -1;
            }
            else
            {
                //数据不足一屏时
                if (rowsCount < maxVisibleRecord)
                {
                    m_lastVisibleIndex = rowsCount - 1;
                    m_firstVisibleIndex = 0;
                }
                //数据超过一屏时
                else
                {
                    //显示中间的数据时
                    if (m_firstVisibleIndex != -1 &&
                        m_lastVisibleIndex != -1 &&
                        !m_lastRecordIsVisible)
                    {
                        int index = getChartIndexByDate(m_lastVisibleKey);
                        if (index != -1)
                        {
                            m_lastVisibleIndex = index;
                        }
                        m_firstVisibleIndex =
                            m_lastVisibleIndex - maxVisibleRecord + 1;
                        if (m_firstVisibleIndex < 0)
                        {
                            m_firstVisibleIndex = 0;
                            m_lastVisibleIndex = m_firstVisibleIndex + maxVisibleRecord;
                            checkChartLastVisibleIndex();
                        }
                    }
                    else
                    {
                        //第一条或最后一条数据被显示时
                        m_lastVisibleIndex = rowsCount - 1;
                        m_firstVisibleIndex =
                            m_lastVisibleIndex - maxVisibleRecord + 1;
                        if (m_firstVisibleIndex > m_lastVisibleIndex)
                        {
                            m_firstVisibleIndex = m_lastVisibleIndex;
                        }
                    }
                }
            }
        }
    }

    /**
     * REF函数
     * @params ticks 数据
     * @params days 日期
     */
    public ArrayList<Double> refValue(ArrayList<Double> ticks, int days)
    {
        ArrayList<Double> refArr = new ArrayList<Double>();
        int length = ticks.size();
        for (int i = 0; i < length; i++)
        {
            double refV = 0;
            if (i >= days)
            {
                refV = ticks.get(i - days);
            }
            else
            {
                refV = ticks.get(0);
            }
            refArr.add(refV);
        }
        return refArr;
    }

    /**
     * 判断是否选中直线
     * @params mp 坐标
     * @params x1 横坐标1
     * @params y1 纵坐标1
     * @params x2 横坐标2
     * @params y2 纵坐标2
     */
    public boolean selectLine(FCPoint mp, double x1, double y1, double x2, double y2)
    {
        lineXY(x1, y1, x2, y2, 0, 0);
        if (!(m_kChart == 0 && m_bChart == 0))
        {
            if (mp.y / (mp.x * m_kChart + m_bChart) >= 0.9 &&
                mp.y / (mp.x * m_kChart + m_bChart) <= 1.1)
            {
                return true;
            }
        }
        else
        {
            if (mp.x >= x1 - m_plotPointSizeChart &&
                mp.x <= x1 + m_plotPointSizeChart)
            {
                return true;
            }
        }
        return false;
    }

    /**
     * 判断是否选中射线
     * @params mp 坐标
     * @params x1 横坐标1
     * @params y1 纵坐标1
     * @params x2 横坐标2
     * @params y2 纵坐标2
     */
    public boolean selectRay(FCPoint mp, double x1, double y1, double x2, double y2)
    {
        lineXY(x1, y1, x2, y2, 0, 0);
        if (!(m_kChart == 0 && m_bChart == 0))
        {
            if (mp.y / (mp.x * m_kChart + m_bChart) >= 0.9 &&
                mp.y / (mp.x * m_kChart + m_bChart) <= 1.1)
            {
                if (x1 >= x2)
                {
                    if (mp.x > x1 + m_plotPointSizeChart)
                    {
                        return false;
                    }
                }
                else if (x1 < x2)
                {
                    if (mp.x < x1 - m_plotPointSizeChart)
                    {
                        return false;
                    }
                }
                return true;
            }
        }
        else
        {
            if (mp.x >= x1 - m_plotPointSizeChart &&
                mp.x <= x1 + m_plotPointSizeChart)
            {
                if (y1 >= y2)
                {
                    if (mp.y <= y1 - m_plotPointSizeChart)
                    {
                        return true;
                    }
                }
                else
                {
                    if (mp.y >= y1 - m_plotPointSizeChart)
                    {
                        return true;
                    }
                }
            }
        }
        return false;
    }

    /**
     * 判断是否选中线段
     * @params mp 坐标
     * @params x1 横坐标1
     * @params y1 纵坐标1
     * @params x2 横坐标2
     * @params y2 纵坐标2
     */
    public boolean selectSegment(FCPoint mp, double x1, double y1, double x2, double y2)
    {
        lineXY(x1, y1, x2, y2, 0, 0);
        double smallX = x1 <= x2 ? x1 : x2;
        double smallY = y1 <= y2 ? y1 : y2;
        double bigX = x1 > x2 ? x1 : x2;
        double bigY = y1 > y2 ? y1 : y2;
        if (mp.x >= smallX - 2 &&
            mp.x <= bigX + 2 &&
            mp.y >= smallY - 2 &&
            mp.y <= bigY + 2)
        {
            if (m_kChart != 0 || m_bChart != 0)
            {
                if (mp.y / (mp.x * m_kChart + m_bChart) >= 0.9 &&
                    mp.y / (mp.x * m_kChart + m_bChart) <= 1.1)
                {
                    return true;
                }
            }
            else
            {
                if (mp.x >= x1 - m_plotPointSizeChart &&
                    mp.x <= x1 + m_plotPointSizeChart)
                {
                    return true;
                }
            }
        }
        return false;
    }

    /**
     * 获取方差数据
     */
    public double standardDeviationSum(ArrayList<Double> listValue, double avgValue)
    {
        double targetValue = listValue.get(listValue.size() - 1);
        double sumValue = (targetValue - avgValue) * (targetValue - avgValue);
        for (int i = 0; i < listValue.size() - 1; i++)
        {
            double ileft = listValue.get(i);
            sumValue = sumValue + (ileft - avgValue) * (ileft - avgValue);
        }
        return sumValue;
    }

    /**
     * 选中画线
     * @params mp 坐标
     */
    public FCPlot selectPlot(FCPoint mp)
    {
         FCPlot sPlot = null;
        m_startMovePlot = false;
        m_selectPlotPoint = -1;
        for (int i = 0; i < m_plots.size(); i++)
        {
            FCPlot plot = m_plots.get(i);
            int index1 = 0, index2 = 0, index3 = 0;
            int mpx1 = 0, mpy1 = 0, mpx2 = 0, mpy2 = 0, mpx3 = 0, mpy3 = 0;
            //检查关键点
            if (plot.m_key1 > 0)
            {
                index1 = getChartIndexByDate(plot.m_key1);
                mpx1 = getChartX(index1);
                mpy1 = getChartY(0, plot.m_value1);
                if (mp.x >= mpx1 - m_plotPointSizeChart &&
                    mp.x <= mpx1 + m_plotPointSizeChart &&
                    mp.y >= mpy1 - m_plotPointSizeChart &&
                    mp.y <= mpy1 + m_plotPointSizeChart)
                {
                    sPlot = plot;
                    m_selectPlotPoint = 0;
                    break;
                }
            }
            if (plot.m_key2 > 0)
            {
                index2 = getChartIndexByDate(plot.m_key2);
                mpx2 = getChartX(index2);
                mpy2 = getChartY(0, plot.m_value2);
                if (mp.x >= mpx2 - m_plotPointSizeChart &&
                    mp.x <= mpx2 + m_plotPointSizeChart &&
                    mp.y >= mpy2 - m_plotPointSizeChart &&
                    mp.y <= mpy2 + m_plotPointSizeChart)
                {
                    sPlot = plot;
                    m_selectPlotPoint = 1;
                    break;
                }
            }
            if (plot.m_key3 > 0)
            {
                index3 = getChartIndexByDate(plot.m_key3);
                mpx3 = getChartX(index3);
                mpy3 = getChartY(0, plot.m_value3);
                if (mp.x >= mpx3 - m_plotPointSizeChart &&
                    mp.x <= mpx3 + m_plotPointSizeChart &&
                    mp.y >= mpy3 - m_plotPointSizeChart &&
                    mp.y <= mpy3 + m_plotPointSizeChart)
                {
                    sPlot = plot;
                    m_selectPlotPoint = 2;
                    break;
                }
            }
            //判断其余部分的选中
            if (m_selectPlotPoint == -1)
            {
                if (plot.m_plotType.equals("Line"))
                {
                    m_startMovePlot = selectLine(mp, mpx1, mpy1, mpx2, mpy2);
                }
                else if (plot.m_plotType.equals("ArrowSegment"))
                {
                    m_startMovePlot = selectSegment(mp, mpx1, mpy1, mpx2, mpy2);
                }
                else if (plot.m_plotType.equals("AngleLine"))
                {
                    m_startMovePlot = selectLine(mp, mpx1, mpy1, mpx2, mpy2);
                    if (!m_startMovePlot)
                    {
                        m_startMovePlot = selectLine(mp, mpx1, mpy1, mpx3, mpy3);
                    }
                }
                else if (plot.m_plotType.equals("Parallel"))
                {
                    m_startMovePlot = selectLine(mp, mpx1, mpy1, mpx2, mpy2);
                    if (!m_startMovePlot)
                    {
                        lineXY(mpx1, mpy1, mpx2, mpy2, 0, 0);
                        double newB = mpy3 - m_kChart * mpx3;
                        if (mpx2 == mpx1)
                        {
                            if (mp.x >= mpx3 - m_plotPointSizeChart &&
                                mp.x <= mpx3 + m_plotPointSizeChart)
                            {
                                m_startMovePlot = true;
                            }
                        }
                        else
                        {
                            double newX1 = m_leftVScaleWidth;
                            double newY1 = newX1 * m_kChart + newB;
                            double newX2 = getSize().cx - m_rightVScaleWidth;
                            double newY2 = newX2 * m_kChart + newB;
                            m_startMovePlot =
                                selectLine(mp, newX1, newY1, newX2, newY2);
                        }
                    }
                }
                else if (plot.m_plotType.equals("LRLine"))
                {
                    m_startMovePlot = selectSegment(mp, mpx1, mpy1, mpx2, mpy2);
                }
                else if (plot.m_plotType.equals("Segment"))
                {
                    m_startMovePlot = selectSegment(mp, mpx1, mpy1, mpx2, mpy2);
                }
                else if (plot.m_plotType.equals("Ray"))
                {
                    m_startMovePlot = selectRay(mp, mpx1, mpy1, mpx2, mpy2);
                }
                else if (plot.m_plotType.equals("Triangle"))
                {
                    m_startMovePlot = selectSegment(mp, mpx1, mpy1, mpx2, mpy2);
                    if (!m_startMovePlot)
                    {
                        m_startMovePlot =
                            selectSegment(mp, mpx2, mpy2, mpx3, mpy3);
                    }
                    if (!m_startMovePlot)
                    {
                        m_startMovePlot =
                            selectSegment(mp, mpx1, mpy1, mpx3, mpy3);
                    }
                }
                else if (plot.m_plotType.equals("SymmetricTriangle"))
                {
                    if (mpx2 != mpx1)
                    {
                        double a = (double)(mpy2 - mpy1) / (double)(mpx2 - mpx1);
                        double b = mpy1 - a * mpx1;
                        double c = -a;
                        double d = mpy3 - c * mpx3;
                        double leftX = m_leftVScaleWidth;
                        double leftY = leftX * a + b;
                        double rightX = getSize().cx - m_rightVScaleWidth;
                        double rightY = rightX * a + b;
                        m_startMovePlot = selectSegment(mp, leftX, leftY, rightX, rightY);
                        if (!m_startMovePlot)
                        {
                            leftY = leftX * c + d;
                            rightY = rightX * c + d;
                            m_startMovePlot = selectSegment(mp, leftX, leftY, rightX, rightY);
                        }
                    }
                    else
                    {
                        double divHeight = getCandleDivHeight();
                        m_startMovePlot = selectSegment(mp, mpx1, 0, mpx1, divHeight);
                        if (!m_startMovePlot)
                        {
                            m_startMovePlot = selectSegment(mp, mpx3, 0, mpx3, divHeight);
                        }
                    }
                }
                else if (plot.m_plotType.equals("Rect"))
                {
                    int sX1 = Math.min(mpx1, mpx2);
                    int sY1 = Math.min(mpy1, mpy2);
                    int sX2 = Math.max(mpx1, mpx2);
                    int sY2 = Math.max(mpy1, mpy2);
                    m_startMovePlot = selectSegment(mp, sX1, sY1, sX2, sY1);
                    if (!m_startMovePlot)
                    {
                        m_startMovePlot = selectSegment(mp, sX2, sY1, sX2, sY2);
                    }
                    if (!m_startMovePlot)
                    {
                        m_startMovePlot = selectSegment(mp, sX1, sY2, sX2, sY2);
                    }
                    if (!m_startMovePlot)
                    {
                        m_startMovePlot = selectSegment(mp, sX1, sY1, sX1, sY2);
                    }
                }
                else if (plot.m_plotType.equals("BoxLine"))
                {
                    int sX1 = Math.min(mpx1, mpx2);
                    int sY1 = Math.min(mpy1, mpy2);
                    int sX2 = Math.max(mpx1, mpx2);
                    int sY2 = Math.max(mpy1, mpy2);
                    m_startMovePlot = selectSegment(mp, sX1, sY1, sX2, sY1);
                    if (!m_startMovePlot)
                    {
                        m_startMovePlot = selectSegment(mp, sX2, sY1, sX2, sY2);
                    }
                    if (!m_startMovePlot)
                    {
                        m_startMovePlot = selectSegment(mp, sX1, sY2, sX2, sY2);
                    }
                    if (!m_startMovePlot)
                    {
                        m_startMovePlot = selectSegment(mp, sX1, sY1, sX1, sY2);
                    }
                }
                else if (plot.m_plotType.equals("TironeLevels"))
                {
                    int sX1 = Math.min(mpx1, mpx2);
                    int sY1 = Math.min(mpy1, mpy2);
                    int sX2 = Math.max(mpx1, mpx2);
                    int sY2 = Math.max(mpy1, mpy2);
                    m_startMovePlot = selectSegment(mp, sX1, sY1, sX2, sY1);
                    if (!m_startMovePlot)
                    {
                        m_startMovePlot = selectSegment(mp, sX1, sY2, sX2, sY2);
                    }
                }
                else if (plot.m_plotType.equals("QuadrantLines"))
                {
                    int sX1 = Math.min(mpx1, mpx2);
                    int sY1 = Math.min(mpy1, mpy2);
                    int sX2 = Math.max(mpx1, mpx2);
                    int sY2 = Math.max(mpy1, mpy2);
                    m_startMovePlot = selectSegment(mp, sX1, sY1, sX2, sY1);
                    if (!m_startMovePlot)
                    {
                        m_startMovePlot = selectSegment(mp, sX1, sY2, sX2, sY2);
                    }
                }
                else if (plot.m_plotType.equals("GoldenRatio"))
                {
                    int sY1 = Math.min(mpy1, mpy2);
                    int sY2 = Math.max(mpy1, mpy2);
                    ArrayList<Double> ranges = new ArrayList<Double>();
                    ranges.add(0.0);
                    ranges.add(0.236);
                    ranges.add(0.382);
                    ranges.add(0.5);
                    ranges.add(0.618);
                    ranges.add(0.809);
                    ranges.add(1.0);
                    ranges.add(1.382);
                    ranges.add(1.618);
                    ranges.add(2.0);
                    ranges.add(2.382);
                    ranges.add(2.618);
                    for (int j = 0; j < ranges.size(); j++)
                    {
                        double newY = sY1 <= sY2
                            ? sY1 + (sY2 - sY1) * ranges.get(j)
                            : sY2 + (sY1 - sY2) * (1 - ranges.get(j));
                        m_startMovePlot = selectSegment(mp, m_leftVScaleWidth,
                            newY, getSize().cx - m_rightVScaleWidth, newY);
                        if (m_startMovePlot)
                        {
                            break;
                        }
                    }
                }
                else if (plot.m_plotType.equals("Cycle"))
                {
                    double r = Math.sqrt(
                        Math.abs((mpx2 - mpx1) * (mpx2 - mpx1) + (mpy2 - mpy1) * (mpy2 - mpy1)));
                    double round =
                        (mp.x - mpx1) * (mp.x - mpx1) + (mp.y - mpy1) * (mp.y - mpy1);
                    if (round / (r * r) >= 0.9 && round / (r * r) <= 1.1)
                    {
                        m_startMovePlot = true;
                    }
                }
                else if (plot.m_plotType.equals("CircumCycle"))
                {
                    ellipseOR(mpx1, mpy1, mpx2, mpy2, mpx3, mpy3);
                    double round = (mp.x - m_oXChart) * (mp.x - m_oXChart) +
                        (mp.y - m_oYChart) * (mp.y - m_oYChart);
                    if (round / (m_rChart * m_rChart) >= 0.9 &&
                        round / (m_rChart * m_rChart) <= 1.1)
                    {
                        m_startMovePlot = true;
                    }
                }
                else if (plot.m_plotType.equals("Ellipse"))
                {
                    double x1 = 0, y1 = 0, x2 = 0, y2 = 0;
                    if (mpx1 <= mpx2)
                    {
                        x1 = mpx2;
                        y1 = mpy2;
                        x2 = mpx1;
                        y2 = mpy1;
                    }
                    else
                    {
                        x1 = mpx1;
                        y1 = mpy1;
                        x2 = mpx2;
                        y2 = mpy2;
                    }
                    double x = x1 - (x1 - x2);
                    double y = 0;
                    double width = (x1 - x2) * 2;
                    double height = 0;
                    if (y1 >= y2)
                    {
                        height = (y1 - y2) * 2;
                    }
                    else
                    {
                        height = (y2 - y1) * 2;
                    }
                    y = y2 - height / 2;
                    double a = width / 2;
                    double b = height / 2;
                    m_startMovePlot = ellipseHasPoint(
                        mp.x, mp.y, x + (width / 2), y + (height / 2), a, b);
                }
                else if (plot.m_plotType.equals("LRBand"))
                {
                    m_startMovePlot = selectSegment(mp, mpx1, mpy1, mpx2, mpy2);
                    if (!m_startMovePlot)
                    {
                        ArrayList<Double> list = new ArrayList<Double>();
                        int minIndex = Math.min(index1, index2);
                        int maxIndex = Math.max(index1, index2);
                        for (int j = minIndex; j <= maxIndex; j++)
                        {
                            list.add(m_datas.get(j).m_close);
                        }
                        linearRegressionEquation(list);
                        getLRBandRange(plot, m_kChart, m_bChart);
                        mpy1 = getChartY(0, plot.m_value1 + m_upSubValue);
                        mpy2 = getChartY(0, plot.m_value2 + m_upSubValue);
                        m_startMovePlot =
                            selectSegment(mp, mpx1, mpy1, mpx2, mpy2);
                        if (!m_startMovePlot)
                        {
                            mpy1 = getChartY(0, plot.m_value1 - m_downSubValue);
                            mpy2 = getChartY(0, plot.m_value2 - m_downSubValue);
                            m_startMovePlot =
                                selectSegment(mp, mpx1, mpy1, mpx2, mpy2);
                        }
                    }
                }
                else if (plot.m_plotType.equals("LRChannel"))
                {
                    lineXY(mpx1, mpy1, mpx2, mpy2, 0, 0);
                    double rightX = getSize().cx - m_rightVScaleWidth;
                    double rightY = rightX * m_kChart + m_bChart;
                    m_startMovePlot =
                        selectSegment(mp, mpx1, mpy1, rightX, rightY);
                    if (!m_startMovePlot)
                    {
                        ArrayList<Double> list = new ArrayList<Double>();
                        int minIndex = Math.min(index1, index2);
                        int maxIndex = Math.max(index1, index2);
                        for (int j = minIndex; j <= maxIndex; j++)
                        {
                            list.add(m_datas.get(j).m_close);
                        }
                        linearRegressionEquation(list);
                        getLRBandRange(plot, m_kChart, m_bChart);
                        mpy1 = getChartY(0, plot.m_value1 + m_upSubValue);
                        mpy2 = getChartY(0, plot.m_value2 + m_upSubValue);
                        lineXY(mpx1, mpy1, mpx2, mpy2, 0, 0);
                        rightY = rightX * m_kChart + m_bChart;
                        m_startMovePlot =
                            selectSegment(mp, mpx1, mpy1, rightX, rightY);
                        if (!m_startMovePlot)
                        {
                            mpy1 = getChartY(0, plot.m_value1 - m_downSubValue);
                            mpy2 = getChartY(0, plot.m_value2 - m_downSubValue);
                            lineXY(mpx1, mpy1, mpx2, mpy2, 0, 0);
                            rightY = rightX * m_kChart + m_bChart;
                            m_startMovePlot =
                                selectSegment(mp, mpx1, mpy1, rightX, rightY);
                        }
                    }
                }
                else if (plot.m_plotType.equals("ParalleGram"))
                {
                    parallelogram(mpx1, mpy1, mpx2, mpy2, mpx3, mpy3);
                    m_startMovePlot = selectSegment(mp, mpx1, mpy1, mpx2, mpy2);
                    if (!m_startMovePlot)
                    {
                        m_startMovePlot =
                            selectSegment(mp, mpx2, mpy2, mpx3, mpy3);
                        if (!m_startMovePlot)
                        {
                            m_startMovePlot = selectSegment(mp, mpx3, mpy3, m_x4Chart, m_y4Chart);
                            if (!m_startMovePlot)
                            {
                                m_startMovePlot = selectSegment(mp, m_x4Chart, m_y4Chart, mpx1, mpy1);
                            }
                        }
                    }
                }
                else if (plot.m_plotType.equals("SpeedResist"))
                {
                    m_startMovePlot = selectSegment(mp, mpx1, mpy1, mpx2, mpy2);
                    if (!m_startMovePlot)
                    {
                        if (mpx1 != mpx2 && mpy1 != mpy2)
                        {
                            FCPoint firstP = new FCPoint((int)mpx2, (int)(mpy2 - (mpy2 - mpy1) / 3));
                            FCPoint secondP = new FCPoint((int)mpx2, (int)(mpy2 - (mpy2 - mpy1) * 2 / 3));
                            FCPoint startP = new FCPoint((int)mpx1, (int)mpy1);
                            double fK = 0, fB = 0, sK = 0, sB = 0;
                            lineXY(startP.x, startP.y, firstP.x, firstP.y, 0, 0);
                            fK = m_kChart;
                            fB = m_bChart;
                            lineXY(startP.x, startP.y, secondP.x, secondP.y, 0, 0);
                            sK = m_kChart;
                            sB = m_bChart;
                            double newYF = 0, newYS = 0;
                            double newX = 0;
                            if (mpx2 > mpx1)
                            {
                                newYF = fK * (getSize().cx - m_rightVScaleWidth) + fB;
                                newYS = sK * (getSize().cx - m_rightVScaleWidth) + sB;
                                newX = (getSize().cx - m_rightVScaleWidth);
                            }
                            else
                            {
                                newYF = fB;
                                newYS = sB;
                                newX = m_leftVScaleWidth;
                            }
                            m_startMovePlot =
                                selectSegment(mp, startP.x, startP.y, newX, newYF);
                            if (!m_startMovePlot)
                            {
                                m_startMovePlot =
                                    selectSegment(mp, startP.x, startP.y, newX, newYS);
                            }
                        }
                    }
                }
                else if (plot.m_plotType.equals("FiboFanline"))
                {
                    m_startMovePlot = selectSegment(mp, mpx1, mpy1, mpx2, mpy2);
                    if (!m_startMovePlot)
                    {
                        if (mpx1 != mpx2 && mpy1 != mpy2)
                        {
                            FCPoint firstP = new FCPoint((int)mpx2, (int)(mpy2 - (mpy2 - mpy1) * 0.382));
                            FCPoint secondP = new FCPoint((int)mpx2, (int)(mpy2 - (mpy2 - mpy1) * 0.5));
                            FCPoint thirdP = new FCPoint((int)mpx2, (int)(mpy2 - (mpy2 - mpy1) * 0.618));
                            FCPoint startP = new FCPoint((int)mpx1, (int)mpy1);
                            ArrayList<FCPoint> listP = new ArrayList<FCPoint>();
                            listP.add(firstP);
                            listP.add(secondP);
                            listP.add(thirdP);
                            int listSize = listP.size();
                            for (int j = 0; j < listSize; j++)
                            {
                                lineXY(startP.x, startP.y, listP.get(j).x, listP.get(j).y, 0, 0);
                                double newX = 0;
                                double newY = 0;
                                if (mpx2 > mpx1)
                                {
                                    newY = m_kChart * (getSize().cx - m_rightVScaleWidth) +
                                        m_bChart;
                                    newX = (getSize().cx - m_rightVScaleWidth);
                                }
                                else
                                {
                                    newY = m_bChart;
                                    newX = m_leftVScaleWidth;
                                }
                                m_startMovePlot =
                                    selectSegment(mp, startP.x, startP.y, newX, newY);
                                if (m_startMovePlot)
                                {
                                    break;
                                }
                            }
                        }
                    }
                }
                else if (plot.m_plotType.equals("FiboTimezone"))
                {
                    int fValue = 1;
                    int aIndex = index1;
                    int pos = 1;
                    int divHeight = getCandleDivHeight();
                    m_startMovePlot =
                        selectSegment(mp, mpx1, 0, mpx1, divHeight);
                    if (!m_startMovePlot)
                    {
                        while (aIndex + fValue <= m_lastVisibleIndex)
                        {
                            fValue = fibonacciValue(pos);
                            int newIndex = aIndex + fValue;
                            int newX = getChartX(newIndex);
                            m_startMovePlot =
                                selectSegment(mp, newX, 0, newX, divHeight);
                            if (m_startMovePlot)
                            {
                                break;
                            }
                            pos++;
                        }
                    }
                }
                else if (plot.m_plotType.equals("Percent"))
                {
                    ArrayList<Integer> list = getPercentParams((double)mpy1, (double)mpy2);
                    for (int j = 0; j < list.size(); j++)
                    {
                        m_startMovePlot = selectSegment(mp, m_leftVScaleWidth,
                            list.get(j), getSize().cx - m_rightVScaleWidth, list.get(j));
                        if (m_startMovePlot)
                        {
                            break;
                        }
                    }
                }
                if (m_startMovePlot)
                {
                    sPlot = plot;
                    plot.m_startKey1 = plot.m_key1;
                    plot.m_startValue1 = plot.m_value1;
                    plot.m_startKey2 = plot.m_key2;
                    plot.m_startValue2 = plot.m_value2;
                    plot.m_startKey3 = plot.m_key3;
                    plot.m_startValue3 = plot.m_value3;
                    break;
                }
            }
        }
        return sPlot;
    }
    
    /**
     * 设置可见索引
     * @params firstVisibleIndex 起始索引
     * @params lastVisibleIndex 结束索引
     */
    public void setChartVisibleIndex(int firstVisibleIndex, int lastVisibleIndex)
    {
        double xScalePixel =
            getChartWorkAreaWidth() / (lastVisibleIndex - firstVisibleIndex + 1);
        if (xScalePixel < 1000000)
        {
            m_firstVisibleIndex = firstVisibleIndex;
            m_lastVisibleIndex = lastVisibleIndex;
            //设置最后一条记录是否可见
            if (lastVisibleIndex != m_datas.size() - 1)
            {
                m_lastRecordIsVisible = false;
            }
            else
            {
                m_lastRecordIsVisible = true;
            }
            m_hScalePixel = xScalePixel;
            checkChartLastVisibleIndex();
        }
    }

    /**
     * 判断是否选中线条
     * @params mp 坐标
     * @params divIndex 层索引
     * @params datas 数据
     * @params curIndex 当前索引
     */
    public boolean selectLines(FCPoint mp, int divIndex, ArrayList<Double> datas, int curIndex)
    {
        if (datas.size() > 0)
        {
            int topY = getChartY(divIndex, datas.get(curIndex));
            if (m_hScalePixel <= 1)
            {
                if (mp.y >= topY - 8 && mp.y <= topY + 8)
                {
                    return true;
                }
            }
            else
            {
                int index = curIndex;
                int scaleX = getChartX(index);
                double judgeTop = 0;
                double judgeScaleX = scaleX;
                if (mp.x >= scaleX)
                {
                    int leftIndex = curIndex + 1;
                    if (curIndex < m_lastVisibleIndex)
                    {
                        double rightValue = datas.get(leftIndex);
                        judgeTop = getChartY(divIndex, rightValue);
                    }
                    else
                    {
                        judgeTop = topY;
                    }
                }
                else
                {
                    judgeScaleX = scaleX - m_hScalePixel;
                    int rightIndex = curIndex - 1;
                    if (curIndex > 0)
                    {
                        double leftValue = datas.get(rightIndex);
                        judgeTop = getChartY(divIndex, leftValue);
                    }
                    else
                    {
                        judgeTop = topY;
                    }
                }
                double lineWidth = 4;
                double judgeX = 0, judgeY = 0, judgeW = 0, judgeH = 0;
                if (judgeTop >= topY)
                {
                    judgeX = judgeScaleX;
                    judgeY = topY - 2 - lineWidth;
                    judgeW = m_hScalePixel;
                    judgeH = judgeTop - topY + lineWidth < 4
                        ? 4
                        : judgeTop - topY + 4 + lineWidth;
                }
                else
                {
                    judgeX = judgeScaleX;
                    judgeY = judgeTop - 2 - lineWidth / 2;
                    judgeW = m_hScalePixel;
                    judgeH = topY - judgeTop + lineWidth < 4
                        ? 4
                        : topY - judgeTop + 4 + lineWidth;
                }

                if (mp.x >= judgeX &&
                    mp.x <= judgeX + judgeW &&
                    mp.y >= judgeY &&
                    mp.y <= judgeY + judgeH)
                {
                    return true;
                }
            }
        }
        return false;
    }

    /**
     * 判断是否在右轴选中线条
     * @params mp 坐标
     * @params divIndex 层索引
     * @params datas 数据
     * @params curIndex 当前索引
     */
    public boolean selectLinesInRight(FCPoint mp, int divIndex, ArrayList<Double> datas, int curIndex)
    {
        if (datas.size() > 0)
        {
            int topY = getChartYInRight(divIndex, datas.get(curIndex));
            if (m_hScalePixel <= 1)
            {
                if (mp.y >= topY - 8 && mp.y <= topY + 8)
                {
                    return true;
                }
            }
            else
            {
                int index = curIndex;
                int scaleX = getChartX(index);
                double judgeTop = 0;
                double judgeScaleX = scaleX;
                if (mp.x >= scaleX)
                {
                    int leftIndex = curIndex + 1;
                    if (curIndex < m_lastVisibleIndex)
                    {
                        double rightValue = datas.get(leftIndex);
                        judgeTop = getChartYInRight(divIndex, rightValue);
                    }
                    else
                    {
                        judgeTop = topY;
                    }
                }
                else
                {
                    judgeScaleX = scaleX - m_hScalePixel;
                    int rightIndex = curIndex - 1;
                    if (curIndex > 0)
                    {
                        double leftValue = datas.get(rightIndex);
                        judgeTop = getChartYInRight(divIndex, leftValue);
                    }
                    else
                    {
                        judgeTop = topY;
                    }
                }
                double lineWidth = 4;
                double judgeX = 0, judgeY = 0, judgeW = 0, judgeH = 0;
                if (judgeTop >= topY)
                {
                    judgeX = judgeScaleX;
                    judgeY = topY - 2 - lineWidth;
                    judgeW = m_hScalePixel;
                    judgeH = judgeTop - topY + lineWidth < 4
                        ? 4
                        : judgeTop - topY + 4 + lineWidth;
                }
                else
                {
                    judgeX = judgeScaleX;
                    judgeY = judgeTop - 2 - lineWidth / 2;
                    judgeW = m_hScalePixel;
                    judgeH = topY - judgeTop + lineWidth < 4
                        ? 4
                        : topY - judgeTop + 4 + lineWidth;
                }

                if (mp.x >= judgeX &&
                    mp.x <= judgeX + judgeW &&
                    mp.y >= judgeY &&
                    mp.y <= judgeY + judgeH)
                {
                    return true;
                }
            }
        }
        return false;
    }
    
    /**
     * 左滚
     * @params step 步长
     */
    public void scrollLeftChart(int step)
    {
        m_targetOldX = 0;
        m_targetOldX2 = 0;
        if (m_showCrossLine)
        {
            m_crossStopIndex = m_crossStopIndex - step;
            if (m_crossStopIndex >= m_firstVisibleIndex)
            {
                step = 0;
            }
            else if (m_crossStopIndex < 0)
            {
                m_crossStopIndex = 0;
            }
        }
        if (step > 0)
        {
            int subIndex = m_lastVisibleIndex - m_firstVisibleIndex;
            int fIndex = m_firstVisibleIndex - step;
            if (fIndex < 0)
            {
                fIndex = 0;
            }
            int eIndex = fIndex + subIndex;
            m_firstVisibleIndex = fIndex;
            m_lastVisibleIndex = eIndex;
        }
        checkChartLastVisibleIndex();
        calculateChartMaxMin();
    }
    
    /**
     * 右滚
     * @params step 步长
     */
    public void scrollRightChart(int step)
    {
        m_targetOldX = 0;
        m_targetOldX2 = 0;
        int dataCount = m_datas.size();
        if (m_showCrossLine)
        {
            m_crossStopIndex = m_crossStopIndex + step;
            if (m_crossStopIndex <= m_lastVisibleIndex)
            {
                step = 0;
            }
            else if (m_crossStopIndex > dataCount - 1)
            {
                m_crossStopIndex = dataCount - 1;
            }
        }
        if (step > 0)
        {
            int subIndex = m_lastVisibleIndex - m_firstVisibleIndex;
            int eIndex = m_lastVisibleIndex + step;
            if (eIndex > dataCount - 1)
            {
                eIndex = dataCount - 1;
            }
            int fIndex = eIndex - subIndex;
            m_firstVisibleIndex = fIndex;
            m_lastVisibleIndex = eIndex;
        }
        checkChartLastVisibleIndex();
        calculateChartMaxMin();
    }
    
    /**
     * 图表的鼠标按下方法
     * @params firstTouch 是否第一次触摸
     * @params firstPoint 第一次触摸的坐标
     * @params secondTouch 是否第二次触摸
     * @params secondPoint 第二次触摸的坐标
     */
    public void touchDownChart(boolean firstTouch, FCPoint firstPoint, boolean secondTouch, FCPoint secondPoint, int clicks)
    {
        m_touchDownPoint = firstPoint;
        m_crossStopIndex = getChartIndex(firstPoint);
        m_targetOldX = 0;
        m_targetOldX2 = 0;
        m_selectShape = "";
        m_selectShapeEx = "";
        m_sPlot = null;
        if (m_datas.size() > 0)
        {
            FCPlot selectedPlot = selectPlot(firstPoint);
            if (selectedPlot != null)
            {
                m_sPlot = selectedPlot;
            }
            if (m_sPlot == null)
            {
                judgeSelectShape(firstPoint);
            }
        }
        if (clicks == 2)
        {
            m_showCrossLine = !m_showCrossLine;
        }
    }

    /**
     * 图表的鼠标移动方法
     * @params firstTouch 是否第一次触摸
     * @params firstPoint 第一次触摸的坐标
     * @params secondTouch 是否第二次触摸
     * @params secondPoint 第二次触摸的坐标
     */
    public void touchMoveChart(boolean firstTouch, FCPoint firstPoint, boolean secondTouch, FCPoint secondPoint)
    {
        if (m_datas.size() == 0)
        {
            return;
        }
        FCPoint mp = firstPoint;
        m_targetOldX = 0;
        m_targetOldX2 = 0;
        m_crossStopIndex = getChartIndex(mp);
        m_touchPosition = mp;
        FCPlot sPlot = m_sPlot;
        if (firstTouch && sPlot != null)
        {
            int newIndex = getChartIndex(mp);
            if (newIndex >= 0 && newIndex < m_datas.size())
            {
                double newDate = getChartDateByIndex(newIndex);
                double newValue = getCandleDivValue(mp);
                if (m_selectPlotPoint == 0)
                {
                    sPlot.m_key1 = newDate;
                    sPlot.m_value1 = newValue;
                }
                else if (m_selectPlotPoint == 1)
                {
                    sPlot.m_key2 = newDate;
                    sPlot.m_value2 = newValue;
                }
                else if (m_selectPlotPoint == 2)
                {
                    sPlot.m_key3 = newDate;
                    sPlot.m_value3 = newValue;
                }
                else if (m_startMovePlot)
                {
                    double bValue = getCandleDivValue(m_touchDownPoint);
                    int bIndex = getChartIndex(m_touchDownPoint);
                    if (sPlot.m_key1 > 0)
                    {
                        sPlot.m_value1 = sPlot.m_startValue1 + (newValue - bValue);
                        int startIndex1 = getChartIndexByDate(sPlot.m_startKey1);
                        int newIndex1 = startIndex1 + (newIndex - bIndex);
                        if (newIndex1 < 0)
                        {
                            newIndex1 = 0;
                        }
                        else if (newIndex1 > m_datas.size() - 1)
                        {
                            newIndex1 = m_datas.size() - 1;
                        }
                        sPlot.m_key1 = getChartDateByIndex(newIndex1);
                    }
                    if (sPlot.m_key2 > 0)
                    {
                        sPlot.m_value2 = sPlot.m_startValue2 + (newValue - bValue);
                        int startIndex2 = getChartIndexByDate(sPlot.m_startKey2);
                        int newIndex2 = startIndex2 + (newIndex - bIndex);
                        if (newIndex2 < 0)
                        {
                            newIndex2 = 0;
                        }
                        else if (newIndex2 > m_datas.size() - 1)
                        {
                            newIndex2 = m_datas.size() - 1;
                        }
                        sPlot.m_key2 = getChartDateByIndex(newIndex2);
                    }
                    if (sPlot.m_key3 > 0)
                    {
                        sPlot.m_value3 = sPlot.m_startValue3 + (newValue - bValue);
                        int startIndex3 = getChartIndexByDate(sPlot.m_startKey3);
                        int newIndex3 = startIndex3 + (newIndex - bIndex);
                        if (newIndex3 < 0)
                        {
                            newIndex3 = 0;
                        }
                        else if (newIndex3 > m_datas.size() - 1)
                        {
                            newIndex3 = m_datas.size() - 1;
                        }
                        sPlot.m_key3 = getChartDateByIndex(newIndex3);
                    }
                }
            }
            return;
        }
        if (firstTouch && secondTouch)
        {
            if (firstPoint.x > secondPoint.x)
            {
                m_firstTouchPointCache = secondPoint;
                m_secondTouchPointCache = firstPoint;
            }
            else
            {
                m_firstTouchPointCache = firstPoint;
                m_secondTouchPointCache = secondPoint;
            }
            if (m_firstTouchIndexCache == -1 ||
                m_secondTouchIndexCache == -1)
            {
                m_firstTouchIndexCache =
                    getChartIndex(m_firstTouchPointCache);
                m_secondTouchIndexCache =
                    getChartIndex(m_secondTouchPointCache);
                m_firstIndexCache = m_firstVisibleIndex;
                m_lastIndexCache = m_lastVisibleIndex;
            }
        }
        else if (firstTouch)
        {
            m_secondTouchIndexCache = -1;
            if (m_firstTouchIndexCache == -1)
            {
                m_firstTouchPointCache = firstPoint;
                m_firstTouchIndexCache =
                    getChartIndex(m_firstTouchPointCache);
                m_firstIndexCache = m_firstVisibleIndex;
                m_lastIndexCache = m_lastVisibleIndex;
                m_firstPaddingTop = m_candlePaddingTop;
                m_firtstPaddingBottom = m_candlePaddingBottom;
            }
        }

        if (firstTouch && secondTouch)
        {
            if (m_firstTouchIndexCache != -1 &&
                m_secondTouchIndexCache != -1)
            {
                FCPoint fPoint = firstPoint;
                FCPoint sPoint = secondPoint;
                if (firstPoint.x > secondPoint.x)
                {
                    fPoint = secondPoint;
                    sPoint = firstPoint;
                }
                double subX = Math.abs(sPoint.x - fPoint.x);
                int subIndex =
                    Math.abs(m_secondTouchIndexCache - m_firstTouchIndexCache);
                if (subX > 0 && subIndex > 0)
                {
                    double newScalePixel = subX / subIndex;
                    if (newScalePixel >= 3)
                    {
                        double intScalePixel = (int)newScalePixel;
                        newScalePixel = intScalePixel;
                    }
                    if (newScalePixel != m_hScalePixel)
                    {
                        int newFirstIndex = m_firstTouchIndexCache;
                        double thisX = fPoint.x;
                        thisX -= newScalePixel;
                        while (thisX > m_leftVScaleWidth + newScalePixel)
                        {
                            newFirstIndex--;
                            if (newFirstIndex < 0)
                            {
                                newFirstIndex = 0;
                                break;
                            }
                            thisX -= newScalePixel;
                        }

                        thisX = sPoint.x;
                        int newSecondIndex = m_secondTouchIndexCache;
                        thisX += newScalePixel;
                        while (
                            thisX < getSize().cx - m_rightVScaleWidth - newScalePixel)
                        {
                            newSecondIndex++;
                            if (newSecondIndex > m_datas.size() - 1)
                            {
                                newSecondIndex = m_datas.size() - 1;
                                break;
                            }
                            thisX += newScalePixel;
                        }
                        setChartVisibleIndex(newFirstIndex, newSecondIndex);
                        int maxVisibleRecord = getChartMaxVisibleCount(m_hScalePixel, getChartWorkAreaWidth());
                        while (maxVisibleRecord <
                                m_lastVisibleIndex - m_firstVisibleIndex + 1 &&
                            m_lastVisibleIndex > m_firstVisibleIndex)
                        {
                            m_lastVisibleIndex--;
                        }
                        checkChartLastVisibleIndex();
                        resetChartVisibleRecord();
                        calculateChartMaxMin();
                    }
                }
            }
        }
        else if (firstTouch)
        {
            if (!m_autoFillHScale)
            {
                int subIndex =
                    (int)((m_firstTouchPointCache.x - firstPoint.x) / m_hScalePixel);
                if (m_allowDragChartDiv)
                {
                    m_candlePaddingTop = m_firstPaddingTop - (m_firstTouchPointCache.y - firstPoint.y);
                    m_candlePaddingBottom = m_firtstPaddingBottom + (m_firstTouchPointCache.y - firstPoint.y);
                }
                int fIndex = m_firstIndexCache + subIndex;
                int lIndex = m_lastIndexCache + subIndex;
                if (fIndex > m_datas.size() - 1)
                {
                    fIndex = m_datas.size() - 1;
                    lIndex = m_datas.size() - 1;
                }
                m_firstVisibleIndex = fIndex;
                m_lastVisibleIndex = lIndex;
                checkChartLastVisibleIndex();
                calculateChartMaxMin();
            }
        }
    }

    /**
     * 更新布局方法
     */
    public void update()
    {
        super.update();
        resetChartVisibleRecord();
        checkChartLastVisibleIndex();
        calculateChartMaxMin();
    }
    
    /**
     * 缩小
     */
    public void zoomOutChart()
    {
        if (!m_autoFillHScale)
        {
            double hScalePixel = m_hScalePixel;
            int oldX = getChartX(m_crossStopIndex);
            if (m_targetOldX == 0)
            {
                m_targetOldX = oldX;
            }
            int pureH = getChartWorkAreaWidth();
            int oriMax = -1, max = -1, deal = 0;
            int dataCount = m_datas.size();
            int findex = m_firstVisibleIndex, lindex = m_lastVisibleIndex;
            if (hScalePixel < pureH)
            {
                oriMax = getChartMaxVisibleCount(hScalePixel, pureH);
                if (dataCount < oriMax)
                {
                    deal = 1;
                }
                if (hScalePixel > 3)
                {
                    hScalePixel += 1;
                }
                else
                {
                    if (hScalePixel == 1)
                    {
                        hScalePixel = 2;
                    }
                    else
                    {
                        hScalePixel = hScalePixel * 1.5;
                        if (hScalePixel > 3)
                        {
                            hScalePixel = (int)hScalePixel;
                        }
                    }
                }
                max = getChartMaxVisibleCount(hScalePixel, pureH);
                if (dataCount >= max)
                {
                    if (deal == 1)
                    {
                        lindex = dataCount - 1;
                    }
                    findex = lindex - max + 1;
                    if (findex < 0)
                    {
                        findex = 0;
                    }
                }
            }
            m_hScalePixel = hScalePixel;
            if (true)
            {
                float sX = m_targetOldX;
                findex = m_crossStopIndex;
                while (sX >= m_leftVScaleWidth + m_hScalePixel / 2)
                {
                    findex = findex - 1;
                    m_offsetX = (float)(sX - m_leftVScaleWidth - m_hScalePixel / 2);
                    sX = (float)(sX - m_hScalePixel);
                }
                findex = findex + 1;
            }
            m_firstVisibleIndex = findex;
            m_lastVisibleIndex = lindex;
            checkChartLastVisibleIndex();
            calculateChartMaxMin();
        }
    }
    
    /**
     * 放大
     */
    public void zoomInChart()
    {
        if (!m_autoFillHScale)
        {
            double hScalePixel = m_hScalePixel;
            int oldX = getChartX(m_crossStopIndex);
            if (m_targetOldX2 == 0)
            {
                m_targetOldX2 = oldX;
            }
            int pureH = getChartWorkAreaWidth();
            int max = -1;
            int dataCount = m_datas.size();
            int findex = m_firstVisibleIndex, lindex = m_lastVisibleIndex;
            if (hScalePixel > 3)
            {
                hScalePixel -= 1;
            }
            else
            {
                hScalePixel = hScalePixel * 2 / 3;
                if (hScalePixel > 3)
                {
                    hScalePixel = (int)hScalePixel;
                }
            }
            max = getChartMaxVisibleCount(hScalePixel, pureH);
            if (max >= dataCount)
            {
                if (hScalePixel < 1)
                {
                    hScalePixel = pureH / (double)max;
                }
                findex = 0;
                lindex = dataCount - 1;
            }
            else
            {
                findex = lindex - max + 1;
                if (findex < 0)
                {
                    findex = 0;
                }
            }
            m_hScalePixel = hScalePixel;
            if (true)
            {
                float sX = m_targetOldX2;
                findex = m_crossStopIndex;
                while (sX >= m_leftVScaleWidth + m_hScalePixel / 2)
                {
                    findex = findex - 1;
                    m_offsetX = (float)(sX - m_leftVScaleWidth - m_hScalePixel / 2);
                    sX = (float)(sX - m_hScalePixel);
                }
                findex = findex + 1;
            }
            m_firstVisibleIndex = findex;
            m_lastVisibleIndex = lindex;
            checkChartLastVisibleIndex();
            calculateChartMaxMin();
        }
    }
}